2017-03-24 30 views
0

私はC++でwin32アプリケーションを作成しています。すべてのiexplorer.exeが閉じられたら、何かをしたいと思っています。私のアプリケーションでiexplorerのイベントをクローズします。

私のケースでは、SetWindowsHook()が役に立ちそうです。

しかし、IEのプロセスIDやスレッドIDが分からないと、IEを開くたびに別のスレッドIDが取得されるためです。

iexplorerのIDを取得するためにプロセスリストを確認するためにタイマーを使用しない場合、win32アプリケーションでIEのcloseイベントを待機する別の方法がありますか?

答えて

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

関連する問題