2017-10-31 41 views
0

どのウィンドウもグローバルに作成されているかどうかを監視したい。私が見つけた最も近いAPIはSetWinEventHookEVENT_OBJECT_CREATEですが、ウィンドウの作成だけでなくコントロールもフックします。私は、あまりにも多くの費用がかからず、CBTウィンドウだけでなく、フックできない方法があるのだろうかと思います。C#でウィンドウの作成/最大化/最小化などのグローバルフック

コールバックhwndがウィンドウhwndかどうかを検出するのにIsWindow()を使用しようとしましたが、hwndがウィンドウまたはコントロールであるかどうかにかかわらず常にtrueを返します。

他のDLLを追加するのではなく、管理されたAPIを使用することをお勧めしますが、絶対に必要な場合はまだ開いています。

最後に、ウィンドウを最大化し、最小化し、復元する方法を教えてください。試しましたEVENT_OBJECT_STATECHANGEしかし、それは正しいものではないようです。 EVENT_SYSTEM_MOVESIZESTARTEVENT_SYSTEM_MOVESIZEENDを試しただけでなく、最大/最小/復元イベントをキャプチャしていません。次のように

部分のコードを見ることができます。事前に

private List<IntPtr> _hooks; 
private User32ex.WinEventDelegate _delegate; 

private void StartService() { 
    _delegate = WinEventProc; 
    _hooks.Add(User32ex.SetWinEventHook(User32.WindowsEventHookType.EVENT_OBJECT_CREATE, User32.WindowsEventHookType.EVENT_OBJECT_DESTROY, IntPtr.Zero, _delegate, 0, 0, User32.WindowsEventHookFlags.WINEVENT_OUTOFCONTEXT)); 
    // Other hooks 
} 

private void WinEventProc(IntPtr hWinEventHook, User32.WindowsEventHookType eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { 
    if (hwnd == IntPtr.Zero || !User32.IsWindow(hwnd)) return; 

    switch (eventType) { 
     case User32.WindowsEventHookType.EVENT_OBJECT_CREATE: 
      Debug.Print($"Create: {hwnd}"); 
      // Do something - here captures all objects not only windows but also controls etc 
      break; 
     case User32.WindowsEventHookType.EVENT_OBJECT_STATECHANGE: 
      Debug.Print($"State change: {hwnd}"); 
      // Do something 
      break; 
     // Other cases 
    } 
} 

多くの感謝!

+0

ハンドルに適用されるウィンドウスタイルを確認する必要があります。 – Lloyd

+0

このようなあいまいな質問に対する通常の答えは、System.Windows.Automation名前空間にあります。 –

+0

@Lloydありがとう。どのWSがウィンドウとコントロールを確実に分離するでしょうか?ありがとう! –

答えて

1

Windows APIの美しい世界へようこそ!あなたのフックが "windows"だけでなく "controls"もフックする理由は、Windowsでは "windows"と "controls"の両方がウィンドウにすぎないということです。異なる種類のウィンドウが異なる場合があり、異なる動作をする可能性があります。コントロールは、特定の外観と特定の動作を持つウィンドウです。

これらのすべてがウィンドウであるため、同時に「コントロール」にフックしない「ウィンドウ」にフックすることはできません。しかし、すでにあなたが1つに夢中になったときに、あなたがフックしたウィンドウがフックしたいウィンドウの種類であるかどうかを特定することができます。コメントに示されているように、ウィンドウスタイルを使用することができます。

// this is a pretty crude and basic way to sort out "controls" 
BOOL isControl_KindOf = GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD; 
+0

ありがとうございます。 MDIチャイルドはいかがですか? WS_CHILDも持っていますか? –

+0

私はそれを覚えていないので、私はgoogle msdnする必要がありました。どうやら、(GetWindowLong(hwnd、GWL_STYLE_EX)&WS_EX_MDICHILD)というmdiの子ウィンドウを識別する別の式が必要です。 – rs232

+0

ありがとう、私は試してみる:) –

関連する問題