使用“hwnd”注册到窗口消息

Posted

技术标签:

【中文标题】使用“hwnd”注册到窗口消息【英文标题】:Register to window messages using 'hwnd' 【发布时间】:2011-06-19 14:23:30 【问题描述】:

假设我有一个有效的 hWnd 到一个活动窗口(例如,它是使用“GetForegroundWindow”或 FindWindow 检索的),我当然可以从另一个应用程序注册到这个 hWnd 的 windows 消息吗?是否有任何 Win32 API 或内置的 C# 方法?

示例:在我的控制台应用程序中,我有一个指向“记事本”窗口的 hWnd(在后台运行)。我可以以某种方式注册指示“记事本”窗口已移动、更改大小、最小化、关闭等的消息吗?

谢谢,

埃拉德

【问题讨论】:

【参考方案1】:

您必须将 DLL 注入拥有该窗口的进程中。使用 SetWindowsHookEx()、WH_CALLWNDPROC 挂钩。您不能使用 C# 语言编写这样的 DLL,该进程不会初始化 CLR 并准备好运行您的代码。本机代码是必需的。检查this project。

【讨论】:

【参考方案2】:

如果您只需要了解它的移动或关闭,请查看SetWinEventHook。您必须为此编写一个 P/Invoke 包装器,因为 .Net API 中没有等价物。您可以使用它而无需注入 DLL(使用 WINEVENT_OUTOFCONTEXT 标志),因此可以将所有内容保留在 C# 中(并且还避免了在单独的 DLL 和主进程之间进行通信的麻烦)。

您可能需要事件 EVENT_OBJECT_LOCATIONCHANGE 和 EVENT_OBJECT_DESTROY。请注意,您会在正在收听的线程上为所有 HWND 获取这些信息,因此您需要在回调中按 HWND 进行过滤。

请注意,当您使用 WINEVENT_OUTOFCONTEXT 时,您自己的代码将需要在调用 SetWinEventHook 的线程上运行一个消息循环。此外,您收到的通知不会立即发送,但会稍有延迟(类似于 PostMessage),但对于您的目的而言,这可能仍然足够快,您可以避免执行进程内挂钩.

在开始编写代码之前,您可以使用 Windows SDK 中的 Accessible Event Watcher 应用 (AccEvent) 查看记事本中可用的消息。

【讨论】:

以上是关于使用“hwnd”注册到窗口消息的主要内容,如果未能解决你的问题,请参考以下文章

向不存在的窗口发送消息好吗?

我使用vc++编程,我使用RegisterClassEx注册了窗口类,怎么用CreateWindow创建该类的MDI窗口?

delphi中SendMessage使用说明

简单的WINDOWS程序问题 为啥没有显示窗口? CREATEWINDOW的第一个参数“已注册的窗口类名”该写啥啊?

深入delphi编程理解之消息WINDOWS原生窗口编写及消息处理过程

delphi代码实现窗口最小化,最大化,关闭消息发送