どのウィンドウもグローバルに作成されているかどうかを監視したい。私が見つけた最も近いAPIはSetWinEventHook
でEVENT_OBJECT_CREATE
ですが、ウィンドウの作成だけでなくコントロールもフックします。私は、あまりにも多くの費用がかからず、CBTウィンドウだけでなく、フックできない方法があるのだろうかと思います。C#でウィンドウの作成/最大化/最小化などのグローバルフック
コールバックhwndがウィンドウhwndかどうかを検出するのにIsWindow()
を使用しようとしましたが、hwndがウィンドウまたはコントロールであるかどうかにかかわらず常にtrueを返します。
他のDLLを追加するのではなく、管理されたAPIを使用することをお勧めしますが、絶対に必要な場合はまだ開いています。
最後に、ウィンドウを最大化し、最小化し、復元する方法を教えてください。試しましたEVENT_OBJECT_STATECHANGE
しかし、それは正しいものではないようです。 EVENT_SYSTEM_MOVESIZESTART
とEVENT_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
}
}
多くの感謝!
ハンドルに適用されるウィンドウスタイルを確認する必要があります。 – Lloyd
このようなあいまいな質問に対する通常の答えは、System.Windows.Automation名前空間にあります。 –
@Lloydありがとう。どのWSがウィンドウとコントロールを確実に分離するでしょうか?ありがとう! –