在 Windows 桌面應用中嵌入 WebBrowser 控制項或自動化 Internet Explorer 時,常需提取當前網頁的所有超連結(``)。本文說明使用標準 COM 介面 IHTMLDocument2、IHTMLElementCollection、IHTMLAnchorElement 逐步枚舉並取得 href 與 hostname 的完整流程與程式碼片段。
IWebBrowser2::get_Document → 取得 IDispatch*,QueryInterface 為 IHTMLDocument2。IHTMLDocument2::get_links → 返回所有 `` 元素的集合 IHTMLElementCollection。IHTMLElementCollection::get_length → 取得連結總數。IHTMLElementCollection::item(index, index) → 取得單一元素的 IDispatch*,QueryInterface 為 IHTMLAnchorElement。IHTMLAnchorElement::get_href / get_hostname → 取得完整 URL 與主機名。// 假設已有 IWebBrowser2* spBrowser
CComPtr<IDispatch> spDispatch;
CComQIPtr<IHTMLDocument2> pDoc2;
if (SUCCEEDED(spBrowser->get_Document(&spDispatch))) {
pDoc2 = spDispatch; // 自動 QI
if (pDoc2) {
CComPtr<IHTMLElementCollection> pElementCol;
if (SUCCEEDED(pDoc2->get_links(&pElementCol))) {
long nCount = 0;
if (SUCCEEDED(pElementCol->get_length(&nCount)) && nCount > 0) {
for (long i = 0; i < nCount; ++i) {
CComVariant idx(i);
CComPtr<IDispatch> spItemDisp;
if (SUCCEEDED(pElementCol->item(idx, idx, &spItemDisp))) {
CComQIPtr<IHTMLAnchorElement> pAnchor(spItemDisp);
if (pAnchor) {
CComBSTR bstrHref, bstrHost;
pAnchor->get_href(&bstrHref);
pAnchor->get_hostname(&bstrHost);
// 將 bstrHref / bstrHost 轉為 CString 或 std::string 存入列表
// 例:m_LinksList.InsertItem(i, CString(bstrHref));
}
}
}
}
}
}
}
IWebBrowser2::get_ReadyState == READYSTATE_COMPLETE 且 Document 非空,否則提取會失敗或不完整。DWebBrowserEvents2::DocumentComplete 事件。CComPtr/CComQIPtr 自動管理參考計數,避免洩漏。若無需即時瀏覽器互動,僅解析靜態 HTML 字串,可直接 CoCreateInstance(CLSID_HTMLDocument) 建立 IHTMLDocument2,呼叫 IPersistStreamInit::Load 載入 HTML,後續提取流程完全相同,效能更高且不依賴 IE 進程。