c# - C# 中用于窗口创建/最大化/最小化等的全局钩子(Hook)

标签 c# hook

我想监视全局创建的任何窗口。我发现的最接近的 API 是 EVENT_OBJECT_CREATE 上的 SetWinEventHook,但是,它不仅可以 Hook 窗口创建,还可以进行控制。不知道有没有什么方法,成本不高,而且不仅可以hook CBT windows。

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

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

最后,如何 Hook 窗口最大化、最小化和恢复事件?尝试了 EVENT_OBJECT_STATEANGE 但似乎不正确。尝试了 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 的美丽世界!你的钩子(Hook)不仅钩住“窗口”,还钩住“控件”,因为在Windows中“窗口”和“控件”都只是窗口。可能有不同类型的窗口,它们的外观和行为可能不同;控件只是具有特定外观和特定行为的窗口。

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

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

关于c# - C# 中用于窗口创建/最大化/最小化等的全局钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47033552/

相关文章:

javascript - 从 Android 浏览器打开 Instagram

c# - C# 中的定时器与全局变量?

c# - 我把我的模拟放在哪里?

php - 错误调用成员函数 get_results()

hook - 安卓应用程序: java/JNI call hooking strategies

c++ - 右 ALT 发送两个虚拟键码

c# - LINQ to XML - 从文件加载 XML 片段

c# - 如何添加时间以使用 .Net(C#) 发送 API 推送消息 (parse.com)

c# - MVC 验证消息国际化

javascript - html输入框 "value"属性内的if语句