針對瀏覽網頁時彈出的大量廣告視窗(本質為無選單、工具列的 IE 視窗),本文實作一個定時掃描桌面視窗、自動識別並關閉廣告視窗的常駐工具。核心邏輯:列舉頂層視窗 → 篩選 IEFrame 類別 → 檢查子視窗結構與可見狀態 → 送出 WM_CLOSE 關閉。
IEFrame。WS_VISIBLE 風格未設定)時,判定為廣告視窗。SetTimer 啟動定時器(如每 500ms)。AfxGetMainWnd()->GetWindow(GW_HWNDFIRST) 取得第一個頂層視窗,迴圈呼叫 GetWindow(GW_HWNDNEXT) 遍歷所有頂層視窗。GetClassName 取得類別名,比對是否為 "IEFrame"。FindWindowEx 尋找 "Worker" / "WorkerA" 子視窗,再尋找其同層下一個子視窗(內容區)。GetWindowLong(hwnd, GWL_STYLE) 檢查內容區子視窗是否具備 WS_VISIBLE 風格。若無,判定為廣告視窗。PostMessage(WM_CLOSE, 0, 0) 關閉。// 列舉頂層視窗
CWnd* pMainWnd = AfxGetMainWnd()->GetWindow(GW_HWNDFIRST);
while (pMainWnd)
{
CString strClassName;
GetClassName(pMainWnd->m_hWnd, strClassName.GetBufferSetLength(100), 100);
strClassName.ReleaseBuffer();
if (strClassName == _T("IEFrame"))
{
// 尋找 Worker / WorkerA 子視窗
CWnd* pChildWnd = CWnd::FromHandle(FindWindowEx(pMainWnd->m_hWnd, NULL, _T("Worker"), NULL));
if (!pChildWnd)
pChildWnd = CWnd::FromHandle(FindWindowEx(pMainWnd->m_hWnd, NULL, _T("WorkerA"), NULL));
if (pChildWnd)
{
// 尋找內容區同層下一個子視窗
CWnd* pChildNextWnd = CWnd::FromHandle(FindWindowEx(pMainWnd->m_hWnd, pChildWnd->m_hWnd, _T("Worker"), NULL));
if (!pChildNextWnd)
pChildNextWnd = CWnd::FromHandle(FindWindowEx(pMainWnd->m_hWnd, pChildWnd->m_hWnd, _T("WorkerA"), NULL));
if (pChildNextWnd)
{
// 檢查是否可見
if (!(GetWindowLong(pChildWnd->m_hWnd, GWL_STYLE) & WS_VISIBLE))
{
CWnd* pTempWnd = pMainWnd;
pTempWnd->PostMessage(WM_CLOSE, 0, 0); // 關閉廣告視窗
return;
}
}
}
}
pMainWnd = pMainWnd->GetWindow(GW_HWNDNEXT);
}
判斷邏輯基於視窗結構啟發式規則,極少數正常 IE 視窗(如某些全螢幕網頁應用)可能被誤關。可引入視窗標題關鍵字比對、網址檢查(透過 IWebBrowser2 介面)等二次驗證機制提高準確度。