首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

WebBrowser 控制項顯示記憶體中 HTML 內容 (IHTMLDocument2 實作)

     編輯:VC 教學

前言

CHtmlView (封裝 WebBrowser ActiveX) 預設僅支援導航至 URL 或檔案路徑。若需直接顯示記憶體中的 HTML 字串 (如動態產生的報表、加密解密後的內容),需利用 IHTMLDocument2 介面操作 DOM。本文示範完整實作流程。

核心思路

  1. 先導航至一個空白 HTML 資源 (建立文件結構)。
  2. 在 OnDocumentComplete 事件中取得 IHTMLDocument2 介面指標。
  3. 呼叫 get_body 取得 IHTMLElement,設定 innerHTML 屬性。

實作步驟

1. 衍生類別 CMemHtmlView

class CMemHtmlView : public CHtmlView
{
    DECLARE_DYNCREATE(CMemHtmlView)
public:
    void NavigateMemory();           // 導航至空白資源
    BOOL PutBodyContent(LPCTSTR pszContent); // 設定 Body 內容
protected:
    virtual void OnDocumentComplete(LPCTSTR lpszURL);
    LPDISPATCH m_pHtmlDoc2;          // IHTMLDocument2 介面指標
    CString m_strBodyContent;        // 快取內容
    BOOL m_bMemoryMode = FALSE;
};

2. 導航至內建空白 HTML 資源

void CMemHtmlView::NavigateMemory()
{
    CString strAppName = AfxGetAppName();
    CString strResID; strResID.Format(_T("%d"), IDR_EMPTY_HTML); // 預先加入空白 HTML 資源

    // Res 協定語法: res://ModuleName/ResourceID
    CString strPath = _T("res://") + strAppName + _T(".exe/") + strResID;

    Navigate2(strPath); // 載入資源中的空白 HTML
    m_bMemoryMode = TRUE;
}

資源準備:在 .rc 加入 HTML 資源 (資源類型 HTML 或自訂 RT_HTML),內容為最小結構:<html><body></body></html>。

3. 文件載入完成後取得 IHTMLDocument2

void CMemHtmlView::OnDocumentComplete(LPCTSTR lpszURL)
{
    if (m_bMemoryMode)
    {
        LPDISPATCH lpDisp = GetHtmlDocument(); // CHtmlView 方法
        if (lpDisp)
        {
            HRESULT hr = lpDisp->QueryInterface(IID_IHTMLDocument2, (void**)&m_pHtmlDoc2);
            if (SUCCEEDED(hr))
                ShowMemoryHtml(); // 設定內容
        }
    }
    CHtmlView::OnDocumentComplete(lpszURL);
}

4. 設定 Body innerHTML

BOOL CMemHtmlView::PutBodyContent(LPCTSTR pszContent)
{
    if (pszContent) m_strBodyContent = pszContent;

    if (!m_pHtmlDoc2) return FALSE;

    HRESULT hr;
    IHTMLElement* pBody = NULL;
    hr = m_pHtmlDoc2->get_body(&pBody);
    if (FAILED(hr) || !pBody) return FALSE;

    _bstr_t bstrContent(m_strBodyContent);
    hr = pBody->put_innerHTML(bstrContent);
    pBody->Release();

    return SUCCEEDED(hr);
}

5. 觸發顯示

void CMemHtmlView::ShowMemoryHtml()
{
    PutBodyContent(m_strBodyContent);
}

使用範例

void CMyView::OnShowReport()
{
    CMemHtmlView* pView = (CMemHtmlView*)GetHtmlView();
    pView->NavigateMemory();

    // 動態產生 HTML
    CString html = _T("

動態報表

時間: ") + CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S")) + _T("

"); pView->PutBodyContent(html); }

關鍵技術點

技術說明
Res 協定存取模組資源:res://ModuleName/ResourceType/ResourceID,類型省略時預設 RT_HTML。
IHTMLDocument2MSHTML DOM 核心介面,提供 get_body, write, createElement 等方法。
innerHTML設定/取得元素內部 HTML 字串,支援完整標記解析。
_bstr_tCOM 字串智慧指標,自動管理 BSTR 記憶體,轉換 CString/LPCTSTR 方便。
時機控制必須在 OnDocumentComplete 後取得介面,否則文件尚未建構完成。

替代方案

  • IPersistStreamInit::Load:直接從記憶體流載入 HTML,無需空白資源中繼。
  • Navigate("about:blank") + document.write():傳統做法,但需處理跨域/安全性限制。
  • WebView2 (Edge Chromium):現代替代方案,支援 NavigateToString 直接載入字串。

結語

利用 IHTMLDocument2 操作 DOM 是 WebBrowser 控制項進階應用的基礎。掌握「資源導航 → 介面查詢 → DOM 操作」三步驟,即可實現記憶體 HTML 顯示、動態報表產生、離線文件渲染等功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved