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 控件”(SHDocVw.dll) 和“Microsoft HTML 对象库”(mshtml.dll) 的引用添加到项目中。它们是 COM 对象,应该在您的“C:\Windows\System32”目录中。