2011-07-28 6 views
4

ウィンドウのアクティブウィンドウ変更イベントをキャプチャしようとしています。ユーザーがVSで作業していて、IEに切り替える場合、このActive Window Changed Eventをキャプチャしたいとします。私はインターネット上で検索し、多くの例が見つかりましたが、何も私のために働くようです。アクティブウィンドウの変更イベントをキャプチャする際の問題

これは私が今までに書いたコードですが、これに何が間違っているのか分かりません。私は誰もが、私はプログラム的または概念的に間違ってやっているものを識別することができ、この

class Program 
{ 
    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); 

    [DllImport("user32.dll")] 
    static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags); 

    private const uint WINEVENT_OUTOFCONTEXT = 0; 
    private const uint EVENT_SYSTEM_FOREGROUND = 3; 

    static void Main(string[] args) 
    { 
     WinEventDelegate dele = new WinEventDelegate(WinEventProc); 
     IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT); 
     Console.ReadKey(); 
    } 

    static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 
    { 
     Console.WriteLine("Something"); 
    } 
} 

WinEventProcを通じて必要なイベントをキャプチャすることができませんと呼ばれることは決してありませんか?私はWindows 7を使用しています

+0

非常に良い、ワーキングソリューションはここにある:http://stackoverflow.com/a/11943387/134761 – angularsen

答えて

5

WinEventsを受け取るためにメッセージをポンピングする必要があります。Console.ReadKey()はそうしない可能性があります。代わりにMessageBoxを使用してテストしてください。後で適切なメッセージループに置き換えてください。 MSDNから

備考:
...
SetWinEventHookはイベントループのANS呼び出しを追加イベント
+0

1あなたは正しいです、私は勝利でこのコードを使用する場合、私は、イベントを取得していますアプリケーションフォーム。任意のアイデアはどのようにコンソールアプリケーションでこれを達成することができますか? –

+0

別の問題は、アクティブウィンドウの変更時にイベントではなくイベントを継続的に取得していることです。何か案は? –

+0

Windowsアプリケーションとコンソールアプリケーションの間には、実際には少し違いがあります。コンソールアプリケーションでウィンドウを作成してメッセージを送信することができます。しかし、最も簡単なことは、おそらくP/InvokeをGetMessage/DispatchMessageにして、プレーンなWin32アプリケーションと同じように使用することです。 ここでVSでブレークポイントを使用していますか?これをVSでデバッグするときは注意してください。ブレークポイントに達するたびにVSがフォアグラウンドに来るため、より多くのメッセージが生成されます。 また、WINEVENT_SKIPOWNTHREADを使用して、独自のメッセージボックスでイベントを受け取らないようにすることもできます。 – BrendanMcK

0

を受信するために、メッセージループを持っている必要があります呼び出すクライアントスレッドあなたのコードを少し変更しました と今はうまく動作しています

public class Program 
{ 
    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); 

    [DllImport("user32.dll")] 
    static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags); 

    private const uint WINEVENT_OUTOFCONTEXT = 0; 
    private const uint EVENT_SYSTEM_FOREGROUND = 3; 

    static void Main(string[] args) 
    { 
     WinEventDelegate dele = new WinEventDelegate(WinEventProc); 
     IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT); 
     EventLoop.Run(); 
     // Console.ReadKey(); 
    } 

    static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 
    { 
     Console.WriteLine(hwnd.ToString()); 
    } 
} 
    public static class EventLoop 
    { 
     public static void Run() 
     { 
      MSG msg; 

      while (true) 
      { 

       if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE)) 
       { 
        if (msg.Message == WM_QUIT) 
         break; 

        TranslateMessage(ref msg); 
        DispatchMessage(ref msg); 
       } 
      } 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct MSG 
     { 
      public IntPtr Hwnd; 
      public uint Message; 
      public IntPtr WParam; 
      public IntPtr LParam; 
      public uint Time; 
     } 

     const uint PM_NOREMOVE = 0; 
     const uint PM_REMOVE = 1; 

     const uint WM_QUIT = 0x0012; 

     [DllImport("user32.dll")] 
     private static extern bool PeekMessage(out MSG lpMsg, IntPtr hwnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); 
     [DllImport("user32.dll")] 
     private static extern bool TranslateMessage(ref MSG lpMsg); 
     [DllImport("user32.dll")] 
     private static extern IntPtr DispatchMessage(ref MSG lpMsg); 
    } 
}e 
関連する問題