CHtmlView (封裝 WebBrowser ActiveX) 預設僅支援導航至 URL 或檔案路徑。若需直接顯示記憶體中的 HTML 字串 (如動態產生的報表、加密解密後的內容),需利用 IHTMLDocument2 介面操作 DOM。本文示範完整實作流程。
OnDocumentComplete 事件中取得 IHTMLDocument2 介面指標。get_body 取得 IHTMLElement,設定 innerHTML 屬性。CMemHtmlViewclass 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;
};
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>。
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);
}
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);
}
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。 |
IHTMLDocument2 | MSHTML DOM 核心介面,提供 get_body, write, createElement 等方法。 |
innerHTML | 設定/取得元素內部 HTML 字串,支援完整標記解析。 |
_bstr_t | COM 字串智慧指標,自動管理 BSTR 記憶體,轉換 CString/LPCTSTR 方便。 |
| 時機控制 | 必須在 OnDocumentComplete 後取得介面,否則文件尚未建構完成。 |
IPersistStreamInit::Load:直接從記憶體流載入 HTML,無需空白資源中繼。Navigate("about:blank") + document.write():傳統做法,但需處理跨域/安全性限制。NavigateToString 直接載入字串。利用 IHTMLDocument2 操作 DOM 是 WebBrowser 控制項進階應用的基礎。掌握「資源導航 → 介面查詢 → DOM 操作」三步驟,即可實現記憶體 HTML 顯示、動態報表產生、離線文件渲染等功能。