介绍
用 VC 编程实现自动关闭弹出式 IE 窗口程序
正文
演示工程下载地址: http://www.megspace.com/computers/bigtime
【实现原理】
弹出式 IE 窗口的特征有:无莱单栏、无工具栏或无状态栏等。
本程序通过循环判断每一个 Shell 窗口(在 Windows 系统中“IE浏览器”、“资源浏览器”和“我的电脑”的窗口都是 Shell 窗口),若满足“无莱单栏”或“无工具栏”或“无状态栏”三个条件之一就认为它是弹出式窗口,然后将它关闭。
本程序的关键是要获得 SHDocVw::IShellWindowsPtr 接口和SHDocVw::IWebBrowser2Ptr 接口(在这里用的是智能指针,也可以使用 raw 指针等)。
【准备工作】
1、在 stdafx.h 文件中加入以下内容:
#pragma warning(disable : 4192)
#pragma warning(disable : 4146)
#import <mshtml.tlb>
#import <shdocvw.dll>
using namespace SHDocVw;
2、在 InitInstance() 函数中加入
AfxOleInit(); // 加载 COM 库
【关键函数】
void AutoClose()
{
// 最大可处理的弹出式 Shell 窗口数,读者可自行修改这个值
const int max_pop_shellwindows_count = 60;
SHDocVw::IShellWindowsPtr ptrWindows = NULL;
IDispatchPtr ptrDispatch = NULL;
;//弹出式IE窗口的 SHDocVw::IWebBrowser2Ptr 指针
SHDocVw::IWebBrowser2Ptr ptrBrowser = NULL
// 用来保存弹出式 Shell 窗口的 SHDocVw::IWebBrowser2Ptr 指针
SHDocVw::IWebBrowser2Ptr ptrBrowser_array[max_pop_shellwindows_count];
_variant_t v;
// 为VARIANT_FALSE 时,表示该 Shell 窗口没有莱单栏
VARIANT_BOOL bMenuBar;
// 为VARIANT_FALSE 时,表示该 Shell 窗口没有状态栏
VARIANT_BOOL bStatusBar;
// 为VARIANT_FALSE 时,表示该 Shell 窗口没有工具栏
int nToolBar;
long j;
long popwin_count = 0; // 弹出式窗口数
long win_count;
HRESULT hr;
// 释放 SHDocVw::IShellWindowsPtr 接口
if (NULL != ptrWindows)
ptrWindows = NULL;
// 创建 SHDocVw::IShellWindowsPtr 接口
hr = ptrWindows.CreateInstance(__uuidof(SHDocVw::ShellWindows));
if (FAILED(hr))
return;
// 得到 Shell 窗口总数
win_count = ptrWindows->Count;
for (long i=0; i<win_count; i++)
{
v = (long)i;
ptrDispatch = ptrWindows->Item(&v);
if (NULL == ptrDispatch)
continue;
// 获得 SHDocVw::IWebBrowser2Ptr 接口
hr = ptrDispatch->QueryInterface(IID_IWebBrowser2, (void **)&ptrBrowser);
if (FAILED(hr))
{
ptrDispatch = NULL;
continue;
}
// 判断是否有莱单栏、状态栏或工具栏
ptrBrowser->get_MenuBar(&bMenuBar);
ptrBrowser->get_StatusBar(&bStatusBar);
ptrBrowser->get_ToolBar(&nToolBar);
// 只要满足下列条件之一就认为是弹出式 Shell 窗口,读者可自行修改条件
if ( (VARIANT_FALSE == bMenuBar) // 没有莱单栏
|| (VARIANT_FALSE == bStatusBar) // 没有状态栏
|| (VARIANT_FALSE == nToolBar) ) // 没有工具栏
{
ptrBrowser_array[popwin_count++] = ptrBrowser;
}
ptrBrowser.Release();
ptrDispatch.Release();
}
for (j=0; j<popwin_count; j++) // 关闭所有弹出式 Shell 窗口
ptrBrowser_array[j]->Quit();
}
【收尾工作】
向对话框程序中添加计时器,然后在 WM_TIMER 事件处理函数 OnTimer() 中加入 AutoClose() 函数。
【一点建议】
建议读者可以在些基础上作成 Windows 服务程序,以使它可以默默地在后台服务。
正文完
(DukeJoe注):虽然本文对弹出式窗口的判断不能让所有人满意,但从技术的角度,他仍然有很多值得我们借签的东西,寻找作者的漏洞,或批评作者的编程思路,是没有意义的,从中学习到我们所需要的知识,才是我们阅读这篇文章的真正目的。