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インターネットコントロール"(SHDocVw.dll)と "Microsoft HTMLオブジェクトライブラリ"(mshtml.dll)の参照をプロジェクトに追加する必要があります。それらは "C:\ Windows \ System32"ディレクトリにあるCOMオブジェクトです。