我正在用C ++编写一个win32应用程序,我希望它能在所有iexplorer.exe关闭时执行某些操作。
我知道SetWindowsHook()在我的情况下可能很有用。
但是如果我不知道IE的进程或线程ID,因为每次打开IE都会获得不同的线程ID。
如果我不使用计时器检查进程列表以获取iexplorer的ID,是否还有另一种方法可以在我的win32应用程序中监听IE的关闭事件?
答案 0 :(得分:0)
IE的对象称为InternetExplorer。 ShellWindows object是InternetExplorer对象的集合。但这里变得复杂了。并非所有InternetExplorer对象都是您所谓的IE窗口。其中一些是“Windows资源管理器”窗口。请参阅About the Browser (Internet Explorer)。
以下是托管C ++控制台程序,它列出了现有窗口并设置了现有窗口数的计数。然后它使用WindowRegistered和WindowRevoked事件来监视窗口的创建和关闭。那些事件没有很好地记录在案。下面的示例使用每个InternetExplorer对象的Document成员来确定窗口是否具有HTML。但请参阅c# - Distinguishing IE windows from other windows when using SHDocVw中的评论; IE窗口可能没有HTML。
请注意,以下示例使用AutoResetEvent来保持程序运行,因为它是一个控制台程序。
以下是标题:
#pragma once
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <ShlObj.h>
#include <comdef.h>
#include <vcclr.h>
以下是该计划:
#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;
}
现在我意识到这种方式存在问题。即使窗口不是IE窗口,WindowRegistered和WindowRevoked处理程序也会递增浏览器计数。我不知道如何确定cookie传递给WindowRegistered和WindowRevoked表示的窗口。几年前,我花了几天或更多的时间来试图解决这个问题。所以你应该做的是以某种方式在每个WindowRegistered和WindowRevoked事件之后重新列出所有窗口。
您需要将“Microsoft Internet Controls”(SHDocVw.dll)和“Microsoft HTML Object Library”(mshtml.dll)的引用添加到项目中。它们是COM对象,应位于“C:\ Windows \ System32”目录中。