用于在C#中创建窗口的全局钩子/最大化/最小化等

时间:2017-10-31 10:50:43

标签: c# hook

我想要监控全局创建的任何窗口。我找到的最近的API是SetWinEventHook EVENT_OBJECT_CREATE,但它不仅会挂钩窗口创建,还会挂起控件。我想知道是否有任何不花费太多的方法,并且不仅可以钩住CBT窗口。

我尝试使用IsWindow()来检测回调hwnd是否是一个窗口hwnd,但无论hwnd是窗口还是控件,它似乎总是返回true。

我更喜欢使用托管api而不是添加其他dll,尽管如果绝对必要,它仍然是一个开放的选项。

最后,如何将窗口最大化,最小化和恢复事件?试过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
    }
}

非常感谢提前!

1 个答案:

答案 0 :(得分:1)

欢迎来到Windows API的美丽世界!你的钩子不仅挂钩&#34; windows&#34;,而且&#34;控制&#34;在Windows中是&#34; windows&#34;和&#34;控制&#34;只是窗户。可能存在不同类型的窗口,它们可能看起来不同并且表现不同;控件只是具有特定外观和特定行为的窗口。

由于所有这些只是窗户,你不能只是挂钩&#34; windows&#34;没有挂钩&#34;控制&#34;同时。但是,当您已经连接到一个时,您可以确定您所连接的窗口是否是您想要挂钩的窗口。正如评论中所建议的那样,您可以使用窗口样式:

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