Использование CHtmlView

#visual-c #mfc

#visual-c #mfc

Вопрос:

В моем приложении MFC я отображаю текст построчно в CScrollView. Теперь новым требованием является отображение текста (а иногда и изображений) в формате html с сохранением всех эффектов, например, жирного шрифта, курсива и т.д. Я знаю, что могу использовать CHtmlView для отображения HTML-файлов, но мне нужно отображать текст, хранящийся в памяти, построчно. Возможно ли это?

Спасибо, Дмитрий

Ответ №1:

Мы делаем что-то подобное для нашего журнала.

Мы просто сохраняем «живой» HTML-документ, добавляем к нему и повторно отображаем его в HTML-представлении.

Мы внедрили небольшой пользовательский HTML-конструктор для наших собственных целей, чтобы добавлять элементы в html.

Вы можете отправить строку в html-документ с чем-то вроде :

     IHTMLDocument2 *document = GetDocument();
    if (document != NULL) 
    {

        // construct text to be written to browser as SAFEARRAY
        SAFEARRAY *safe_array = SafeArrayCreateVector(VT_VARIANT,0,1);

        VARIANT *variant;
        // string contains the HTML data.
        // convert char* string to OLEstring

        CComBSTR bstrTmp = string;

        SafeArrayAccessData(safe_array,(LPVOID *)amp;variant);
        variant->vt = VT_BSTR;
        variant->bstrVal = bstrTmp;
        SafeArrayUnaccessData(safe_array);

        // write SAFEARRAY to browser document to append string
        document->write(safe_array);

        //Detach CComBSTR since string will be freed by SafeArrayDestroy
        bstrTmp.Detach();

        //free safe_array
        SafeArrayDestroy(safe_array);

        //release document
        document->Release();
    }
  

Макс.

Ответ №2:

Решение очень простое

Дождитесь завершения загрузки документа, перегрузив функцию OnDocumentComplete

 CHtmlView::OnDocumentComplete( LPCTSTR lpszURL)
{

IHTMLDocument2 *document = GetDocument();

IHTMLElement* pBody = document->get_body();

BSTR str = "your HTML";

pBody-> put_innerHTML(str);

document->close();
document->Release();
}
  

Комментарии:

1. Действительно ли это отвечает на вопрос?

2. ДА. Требовалось отображать в памяти HTML с помощью CHtmlView, и вы можете загрузить свой HTML в строку «BSTR str» для отображения в CHtmlView

Ответ №3:

Невозможно просто сгенерировать HTML в строке памяти и вставить его в CHtmlView.

Наше решение (которое работает довольно хорошо) заключается в создании временного html-файла (во временном каталоге Windows) и переходе из представления cHTML к этому файлу. В принципе:

 OurTempFileClass theTempFile;
theTempFile.GetStream()->Put(mHTMLString.Get(), mHTMLString.GetLength());

CHtmlCtrl theHtmlCtrl;
theHtmlCtrl.Navigate2(theTempFile->GetFullPath());
  

(это псевдокод, потому что мы не используем классы stdlib c .

Комментарии:

1. Большое вам спасибо за ваш ответ. У меня есть существующее приложение, и его представление является производным от CScrollView. Возможно ли преобразовать его для использования вместо CHtmlView? Я заменил базовый класс на CScrollView и заставил <code>аннулировать CBookView::onDraw(CDC* pDC) { Navigate2(«C:\Shared\Monte\mp3Text\13.html «); }</code> Но ничего не отображается.

2. Я не совсем понимаю отношения наследования, но я не думаю, что вам следует вызывать функцию Navigate () в собственной функции onDraw (). Если вы переопределите onDraw(), то в этой функции должно произойти все, что должно отображаться. В этом случае функция CHtmlView::onDraw (которая отображает содержимое HTML) никогда не используется, потому что вы заменили ее своей собственной функцией onDraw.

3. Но что еще должно отображаться, кроме того, что я сам указываю? До перехода на CHtmlView я всегда использовал TextOut () в моем собственном onDraw(). Я решил создать новое приложение на основе CHtmlView, если изменить мое существующее приложение слишком проблематично. Но я не знаю, откуда вызывать Navigate2(). В примерах, которые я нашел, это вызывается из OnInitialUpdate(), но я хочу отображать содержимое динамически на основе документа, который я открываю. Не могли бы вы, пожалуйста, сказать мне, как я могу это сделать?

4. Кроме того, здесь ms-news.net/f3292 / … кто-то утверждает, что он предоставляет способ загрузки содержимого из памяти, но я не вижу достаточно информации, чтобы понять, как это делается. Может быть, вы могли бы дать какие-либо комментарии по этому поводу? Большое вам спасибо.

5. По ссылке выше я вижу только вопрос, но никто не утверждает, что это возможно отобразить из памяти. CHtmlView использует IE для отображения содержимого HTML. У вас нет полного контроля над функциональностью рендеринга, поэтому onDraw () определенно не то место. Каждый раз, когда содержимое, которое вы хотите отобразить, изменяется, вам нужно сгенерировать временный файл и снова вызвать Navigate2(). Вы можете сделать это в любой программе, которую вы хотите (даже за пределами вашего класса, производного от CHtmlView).