在 VC++ 應用中嵌入 WebBrowser 控件 (CHtmlView 或 ActiveX WebBrowser) 後,常需從 C++ 呼叫頁面內的 JavaScript 函數。本文提供標準 COM 介面調用代碼:獲取 IHTMLDocument2 → IHTMLWindow2 → execScript 執行 JS 代碼並可選取得返回值。
// 假設 m_browser 為 CWebBrowser2 或 CHtmlView 成員
// 1. 獲取 Document 介面
CComPtr pDisp;
m_browser->get_Document(&pDisp);
if (!pDisp) return;
CComPtr pDoc;
pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
if (!pDoc) return;
// 2. 獲取 Window 介面 (執行腳本上下文)
CComPtr pWin;
pDoc->get_parentWindow(&pWin);
if (!pWin) return;
// 3. 構建 JS 代碼字串 (可含參數)
CString jsCode;
jsCode.Format(_T("CategHandle('%d','%s','%d','yes')"),
g_nGroupIndex + 1, dlg.m_vFileGroup[g_nGroupIndex].strGroup, dlg.m_vFileGroup.size());
// 4. 執行腳本
CComBSTR bstrCode(jsCode);
CComBSTR bstrLang(_T("JavaScript")); // 或 JScript
VARIANT varResult; VariantInit(&varResult);
HRESULT hr = pWin->execScript(bstrCode, bstrLang, &varResult);
if (SUCCEEDED(hr)) {
// varResult 為 JS 返回值 (若函數有 return)
// 可轉換: CString ret = (BSTR)varResult.bstrVal;
}
| 介面 | 來源 | 用途 |
|---|---|---|
IWebBrowser2::get_Document | WebBrowser 控件 | 獲取當前文檔的 IDispatch |
IHTMLDocument2 | MSHTML.dll | DOM 文檔操作核心介面 |
IHTMLDocument2::get_parentWindow | MSHTML | 獲取 IHTMLWindow2 (window 物件) |
IHTMLWindow2::execScript | MSHTML | 在窗口上下文執行腳本代碼 |
bstrLang 傳 L\"JavaScript\" 或 L\"JScript\" (IE 內建),VBScript 需系統支援。execScript 可能因同源策略失敗。DocumentComplete 事件後調用,確保 DOM 就緒。VARIANT 類型視 JS 返回值而定 (VT_BSTR, VT_I4, VT_BOOL, VT_DISPATCH 等),需安全轉換。IHTMLWindow2::eval (僅評估運算式)、IDispatch::Invoke 直接呼叫 JS 函數 (需 DISPID),execScript 最通用。若需 JS 主動呼叫 C++,可實現 IDispatch 介面的 C++ 物件,並透過 IHTMLWindow2::set_property 或 window.external (需 IDocHostUIHandler::GetExternal) 暴露給 JS。此為另一主題。
此片段適用於所有嵌入 MSHTML/WebBrowser 的 VC++ 專案 (MFC/ATL/WTL/純 SDK)。