在我的应用程序中侦听关闭iexplorer事件 我正在用C++编写Win32应用程序,我希望它在所有iExtru.EXE都关闭的时候做一些事情。p>

在我的应用程序中侦听关闭iexplorer事件 我正在用C++编写Win32应用程序,我希望它在所有iExtru.EXE都关闭的时候做一些事情。p>,c++,windows,setwindowshookex,C++,Windows,Setwindowshookex,我知道SetWindowsHook()在我的情况下可能很有用 但是如果我不知道IE的进程或线程ID,因为每次打开IE都会得到不同的线程ID 如果我不使用计时器检查进程列表以获取iexplorer的ID,那么在我的win32应用程序中是否有其他方法来侦听IE的关闭事件?调用IE的对象。是InternetExplorer对象的集合。但这里情况变得复杂了。并非所有InternetExplorer对象都是您所称的IE窗口。其中一些是“Windows资源管理器”窗口。看 下面是一个托管C++控制台程序,列

我知道SetWindowsHook()在我的情况下可能很有用

但是如果我不知道IE的进程或线程ID,因为每次打开IE都会得到不同的线程ID


如果我不使用计时器检查进程列表以获取iexplorer的ID,那么在我的win32应用程序中是否有其他方法来侦听IE的关闭事件?

调用IE的对象。是InternetExplorer对象的集合。但这里情况变得复杂了。并非所有InternetExplorer对象都是您所称的IE窗口。其中一些是“Windows资源管理器”窗口。看

下面是一个托管C++控制台程序,列出现有窗口并设置现有窗口数的计数。然后,它使用WindowRegistered和WindowReversed事件来监视窗口的创建和关闭。这些事件没有很好的记录。下面的示例使用每个InternetExplorer对象的文档成员来确定窗口是否包含HTML。但是,请参见中的评论;IE窗口中可能没有HTML

请注意,以下示例使用AutoResetEvent保持程序运行,因为它是一个控制台程序

以下是标题:

#pragma once

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <ShlObj.h>
#include <comdef.h>
#include <vcclr.h>
#pragma一次
#包括
#包括
#包括
#包括
#包括
#包括
节目内容如下:

#include "stdafx.h"
using namespace System;
using namespace System::Threading;

static int Browsers = 0;
static gcroot<AutoResetEvent^> Event;

bool IsBrowser(SHDocVw::InternetExplorer ^ ie)
{
    MSHTML::IHTMLDocument2^ Document;
    try { Document = (MSHTML::IHTMLDocument2^)ie->Document; }
    catch (Exception^ ex)
    {
        return false;
    }
    return Document != nullptr;
}

 static void WindowRegistered(int lCookie) {
    ++Browsers;
    Console::WriteLine("WindowRegistered");
}

static void WindowRevoked(int lCookie) {
    --Browsers;
    Console::WriteLine("WindowRevoked");
    if (Browsers <= 0)
        Event->Set();
}

int main(array<System::String ^> ^args)
{
    SHDocVw::ShellWindows^ swList = gcnew SHDocVw::ShellWindowsClass();
    Console::WriteLine(L"{0} instances", swList->Count);
    for each (SHDocVw::InternetExplorer ^ ie in swList) {
        Console::WriteLine(ie->LocationURL);
        if (IsBrowser(ie)) {
            Console::WriteLine("HTML document");
            ++Browsers;
        }
        else
            Console::WriteLine("Not HTML");
        }
    if (Browsers == 0)
    {
        Console::WriteLine("No browsers");
        return 0;
    }
    Event = gcnew AutoResetEvent(false);
    swList->WindowRegistered += gcnew SHDocVw::DShellWindowsEvents_WindowRegisteredEventHandler(WindowRegistered);
    swList->WindowRevoked += gcnew SHDocVw::DShellWindowsEvents_WindowRevokedEventHandler(WindowRevoked);
    Event->WaitOne();
    Console::WriteLine("No more browsers");
    return 0;
}
#包括“stdafx.h”
使用名称空间系统;
使用名称空间系统::线程;
静态int=0;
静态根事件;
bool-IsBrowser(SHDocVw::InternetExplorer^ie)
{
MSHTML::IHTMLDocument2^文档;
尝试{Document=(MSHTML::IHTMLDocument2^)ie->Document;}
捕获(异常^ex)
{
返回false;
}
退货单据!=nullptr;
}
静态无效窗口已注册(int lCookie){
++浏览器;
控制台::WriteLine(“WindowRegistered”);
}
静态无效窗口已撤销(int lCookie){
--浏览器;
控制台::WriteLine(“窗口撤销”);
if(浏览器集();
}
int main(数组^args)
{
SHDocVw::ShellWindows^swList=gcnew SHDocVw::ShellWindowsClass();
控制台::WriteLine(L“{0}个实例”,swList->Count);
对于每个(SHDocVw::InternetExplorer^ie在swList中){
控制台::WriteLine(即->位置URL);
如果(IsBrowser(ie)){
控制台::WriteLine(“HTML文档”);
++浏览器;
}
其他的
控制台::WriteLine(“非HTML”);
}
如果(浏览器==0)
{
控制台::WriteLine(“无浏览器”);
返回0;
}
事件=gcnew AutoResetEvent(假);
swList->WindowRegistered+=gcnew SHDocVw::DShellWindowsEvents\u WindowRegisteredEventHandler(WindowRegistered);
swList->WindowRevecated+=gcnew SHDocVw::DShellWindowsEvents\u WindowRevokedEventHandler(WindowRevecated);
事件->WaitOne();
控制台::WriteLine(“不再有浏览器”);
返回0;
}
现在我才意识到这种工作方式存在问题。WindowRegistered和WindowReversed处理程序正在增加浏览器计数,即使窗口不是IE窗口。我不知道如何确定cookie传递给WindowRegistered和WindowReversed的窗口代表什么。几年前,我花了几年时间ys或更多试图找出答案。因此,您应该在每个WindowRegistered和WindowReversed事件之后以某种方式重新列出所有窗口

您需要将“Microsoft Internet控件”(SHDocVw.dll)和“Microsoft HTML对象库”(mshtml.dll)的引用添加到项目中。它们是COM对象,应该位于“C:\Windows\System32”目录中