MFC 文檔/視圖架構將 View、Frame、Document 緊密綁定。若想將 CHtmlView 如同一般控制項般放入對話方塊,必須解決兩大難題:
CHtmlCtrl 像 CButton 一樣隨意置入對話方塊?利用 CStatic 控制項作為佔位符,透過 SubclassDlgItem 將其替換為 CHtmlCtrl,保持相同 ID、尺寸與位置。
本質相同,僅使用方式不同。View 專為文檔/視圖架構設計,擁有 m_pDocument 指標並固定於 CFrameWnd 中。但 m_pDocument 可為 NULL,CHtmlView 實際使用 IWebBrowser2,與 MFC 文檔架構無關。
處理 WM_MOUSEACTIVE 時呼叫 GetParentFrame() 並啟動視圖,假設父視窗為 CFrameWnd。解決:覆寫直接呼叫 CWnd::OnMouseActive 繞過 Frame 邏輯。
銷毀時呼叫 GetParentFrame() 並停用視圖。解決:覆寫直接呼叫 CWnd::OnDestroy。
預設 delete this,適合堆積建立的 View,但控制項通常為父視窗成員變數,不應自我刪除。解決:覆寫為空實作。
int CHtmlCtrl::OnMouseActive(...) {
return CWnd::OnMouseActive(...); // 繞過 CView doc/frame 邏輯
}
void CHtmlCtrl::OnDestroy() {
CWnd::OnDestroy(); // 繞過 CView doc/frame 邏輯
}
void CHtmlCtrl::PostNcDestroy() {
// 不執行 delete this
}
資源檔嵌入 HTML、圖片、音效:
ABOUT.HTML HTML DISCARDABLE "res\about.htm"
VCKBCOM.GIF HTML DISCARDABLE "res\vckcom.gif"
OKUP.GIF HTML DISCARDABLE "res\okup.gif"
OKDN.GIF HTML DISCARDABLE "res\okdn.gif"
MOZART.WAV HTML DISCARDABLE "res\mozart.wav"
HTML 中使用 res: 協定定位資源:
<BASE url="res://AboutHtml.exe/about.htm">
<IMG src="vckcom.gif"> <!-- 瀏覽器自動解析為 res://AboutHtml.exe/vckcom.gif -->
BOOL CAboutDialog::OnInitDialog() {
CDialog::OnInitDialog();
VERIFY(m_page.CreateFromStatic(IDC_HTMLVIEW, this));
m_page.LoadFromResource(_T("about.htm"));
return TRUE;
}
BOOL CHtmlCtrl::CreateFromStatic(UINT nID, CWnd* pParent) {
CStatic wndStatic;
if (!wndStatic.SubclassDlgItem(nID, pParent)) return FALSE;
CRect rc; wndStatic.GetWindowRect(&rc); pParent->ScreenToClient(&rc);
wndStatic.DestroyWindow();
return Create(NULL, NULL, WS_CHILD | WS_VISIBLE, rc, pParent, nID, NULL);
}
app:OK 按鈕實為圖片連結 <A href="app:ok"><IMG ...></A>。點擊觸發 CHtmlCtrl::OnBeforeNavigate2,攔截 app: 協定並轉派虛擬函式 OnAppCmd:
void CMyHtmlCtrl::OnAppCmd(LPCTSTR lpszWhere) {
if (_tcsicmp(lpszWhere, _T("ok")) == 0)
GetParent()->SendMessage(WM_COMMAND, IDOK);
}
可擴充 app:cancel、app:refresh 等指令,實現豐富互動。
<body oncontextmenu="return false"> 禁用,或以子類化方式攔截。