IWebBrowser2 // 瀏覽器控制核心:導航、文檔存取
→ get_Document() → IDispatch
→ QueryInterface → IHTMLDocument2 (MSHTML DOM 根)
→ get_all() → IHTMLElementCollection (所有元素)
→ getElementById/TagName → IHTMLElement (單一元素)
→ createEventObject / fireEvent → 事件模擬
// 取得 IHTMLDocument2*
IHTMLDocument2* pDoc = nullptr;
pWebBrowser->get_Document((IDispatch**)&pDoc);
if (!pDoc) return;
// 方法 A:依 Tag 取得集合
IHTMLElementCollection* pColl = nullptr;
pDoc->get_all(&pColl);
// 方法 B:依 ID 直接取得
IHTMLElement* pElem = nullptr;
pDoc->getElementById(CComBSTR(_T("targetId")), &pElem);
// 方法 C:依 TagName 取得集合再遍歷
IHTMLElementCollection* pTags = nullptr;
pDoc->getElementsByTagName(CComBSTR(_T("a")), &pTags);
long len = 0; pTags->get_length(&len);
for (long i = 0; i < len; ++i) {
CComVariant idx(i), idx2(0);
CComPtr pDisp;
pTags->item(idx, idx2, &pDisp);
CComQIPtr pEl(pDisp);
CComBSTR innerText, href;
pEl->get_innerText(&innerText);
pEl->getAttribute(CComBSTR(_T("href")), 0, &href);
// 判斷是否目標連結...
}
IXMLHTTPRequest* pHttp = nullptr;
CoCreateInstance(CLSID_XMLHTTP, NULL, CLSCTX_INPROC_SERVER,
IID_IXMLHTTPRequest, (void**)&pHttp);
pHttp->open(CComBSTR(_T("GET")), CComBSTR(url), VARIANT_FALSE, vtEmpty, vtEmpty);
pHttp->send(vtEmpty);
long status = 0; pHttp->get_status(&status);
if (status == 200) {
CComBSTR responseText;
pHttp->get_responseText(&responseText);
// CString str = responseText; 正則/字串搜尋提取...
}
// 通用輸入框
void SetInputValue(IHTMLElementCollection* pAll, LPCTSTR name, LPCTSTR value) {
CComPtr pDisp;
pAll->item(CComVariant(name), CComVariant(0L), &pDisp);
CComQIPtr pInput(pDisp);
if (pInput) pInput->put_value(CComBSTR(value));
}
// 下拉選單
void SetSelectValue(IHTMLElementCollection* pAll, LPCTSTR name, long index) {
CComPtr pDisp;
pAll->item(CComVariant(name), CComVariant(0L), &pDisp);
CComQIPtr pSelect(pDisp);
if (pSelect) pSelect->put_selectedIndex(index);
}
// 文字區域
void SetTextareaValue(IHTMLElementCollection* pAll, LPCTSTR name, LPCTSTR value) {
CComPtr pDisp;
pAll->item(CComVariant(name), CComVariant(0L), &pDisp);
CComQIPtr pTextarea(pDisp);
if (pTextarea) pTextarea->put_value(CComBSTR(value));
}
IObjectWithSite::SetSite 取得 IWebBrowser2DWebBrowserEvents2::DocumentComplete 事件DocumentComplete 中:pDisp->QueryInterface(IID_IHTMLDocument2) → HTMLDocumentEvents2::onclick 連接IHTMLEventObj* pEvtObj → get_srcElement() 取得觸發元素 → 解析屬性
// BHO 事件連接片段
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* pDisp, VARIANT* URL) {
CComQIPtr pDoc(pDisp);
if (!pDoc) return;
CComQIPtr pDocEvents(pDoc);
if (pDocEvents) {
// 建議使用 AtlAdvise 連接事件汲
// 需實作 IDispatch Invoke 捕獲 DISPID_HTMLDOCUMENTEVENTS2_ONCLICK
}
}
| 介面 | 用途 | 常用方法 |
|---|---|---|
| IWebBrowser2 | 瀏覽器控制 | Navigate, get_Document, ExecWB, Quit |
| IHTMLDocument2 | DOM 文檔根 | get_all, getElementById, getElementsByTagName, createElement |
| IHTMLElement | 通用元素 | get_innerText, put_innerText, getAttribute, setAttribute, click |
| IHTMLInputElement | <input> 專用 | put_value, get_value, get_type |
| IHTMLSelectElement | <select> 專用 | put_selectedIndex, get_options, add/remove |
| IHTMLTextAreaElement | <textarea> 專用 | put_value, get_value |
| IHTMLEventObj | 事件物件 | get_srcElement, get_type, get_keyCode, returnValue |
QueryInterface/get_* 取得的介面指標必須 Release(),建議使用 CComPtr/CComQIPtr 智慧指標IWebBrowser2::get_ReadyState == READYSTATE_COMPLETEget_innerText 回傳 BSTR (UTF-16),轉換用 CW2A/CW2T 或 WideCharToMultiByteHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{CLSID}掌握 IWebBrowser2 → IHTMLDocument2 → IHTMLElementCollection → IHTMLElement 介面鏈,配合 IXMLHTTPRequest 輕量抓取與 BHO 事件捕獲,即可構建強大的網頁自動化、資料擷取、測試工具。