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



我想监视全局创建的任何窗口。我找到的最接近的 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
    }
}

提前非常感谢!

歡迎來到 Windows API 的美麗世界!您的钩子不仅钩住"窗口",还钩住"控件"的原因是,在Windows中,"窗口"和"控件"都只是窗口。可能有不同类型的窗口,它们可能看起来不同,行为也不同;控件只是具有特定外观和特定行为的窗口。

由于它们都只是窗口,因此您不能只挂接到"窗口"而不同时挂接到"控件"。但是,当您已经挂钩到一个窗口时,您可以确定您挂钩到的窗口是否是您想要挂钩的窗口类型。如评论中所建议的,您可以使用窗口样式:

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

最新更新