透過 SHDocVw.ShellWindows 列舉系統中所有 IE 視窗,配合 MSHTML 解析 DOM,可獲取指定 IE 視窗的 URL 並提取完整網頁原始碼。
// stdafx.h 或對應頭文件
#import
#import
// 命名空間 (視匯入產生的 tlh/tli 而定)
using namespace SHDocVw;
using namespace MSHTML;
void CGetIESrcDlg::GetRunningIESrc() {
CoInitialize(NULL);
IShellWindowsPtr spShellWindows;
HRESULT hr = spShellWindows.CreateInstance(__uuidof(ShellWindows));
if (FAILED(hr)) {
AfxMessageBox(_T("Shell Windows 介面不可用"));
CoUninitialize();
return;
}
long nCount = spShellWindows->GetCount();
for (long i = 0; i < nCount; i++) {
_variant_t vaIndex(i, VT_I4);
IDispatchPtr spDisp = spShellWindows->Item(vaIndex);
IWebBrowser2Ptr spBrowser(spDisp); // QueryInterface 自動轉型
if (!spBrowser) continue;
IDispatchPtr spDocDisp;
if (SUCCEEDED(spBrowser->get_Document(&spDocDisp)) && spDocDisp) {
IHTMLDocument2Ptr spHtmlDoc(spDocDisp);
if (!spHtmlDoc) continue;
// 1. 獲取 URL
_bstr_t bstrUrl = spBrowser->GetLocationURL();
AfxMessageBox(CString(bstrUrl)); // 顯示 URL
// 2. 獲取完整 HTML 原始碼
IHTMLDocument3Ptr spHtmlDoc3;
hr = spHtmlDoc->QueryInterface(__uuidof(IHTMLDocument3), (void**)&spHtmlDoc3);
if (SUCCEEDED(hr) && spHtmlDoc3) {
IHTMLElementPtr spDocElement;
hr = spHtmlDoc3->get_documentElement(&spDocElement);
if (SUCCEEDED(hr) && spDocElement) {
BSTR bstrHtml;
hr = spDocElement->get_outerHTML(&bstrHtml);
if (SUCCEEDED(hr) && bstrHtml) {
AfxMessageBox(CString(bstrHtml)); // 顯示完整 HTML
SysFreeString(bstrHtml);
}
spDocElement->Release();
}
spHtmlDoc3->Release();
}
break; // 僅處理第一個找到的 IE 視窗 (示範用)
}
}
CoUninitialize();
}
Item(index) 取得 IDispatchget_Document 取得文件物件,GetLocationURL 取得 URLIHTMLDocument2/3:文件介面get_documentElement:取得 <html> 根元素get_outerHTML:取得含標籤的完整 HTML 字串_com_ptr_t 衍生類別 (Ptr 後綴) 自動管理 AddRef/ReleaseSysAllocString/SysFreeString 配對,_bstr_t 為封裝類別IWebBrowser2 進程,需透過 IWebBrowser2::get_HWND 對應視窗控制代碼區分IHTMLDocument2,可遍歷 ShellWindows 並比對 HWND 定位特定標籤outerHTML 可能極大 (MB 級),AfxMessageBox 會卡死,實際應用應寫入檔案或串流處理HRESULTCoInitialize/CoUninitialize 配對,考慮 COINIT_APARTMENTTHREADED_com_ptr_t 智慧指標自動釋放