avisnet's blog

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
 关键字 弹出式 IE 浏览器
原作者姓名 易剑
源地址:http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=646

介绍
用 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注):虽然本文对弹出式窗口的判断不能让所有人满意,但从技术的角度,他仍然有很多值得我们借签的东西,寻找作者的漏洞,或批评作者的编程思路,是没有意义的,从中学习到我们所需要的知识,才是我们阅读这篇文章的真正目的。

posted on 2006-10-19 08:45  avisnet  阅读(731)  评论(2编辑  收藏  举报