在 C# 中监听另一个窗口调整大小事件
我正在实现一个小型应用程序(观察者),它需要将自身“附加”到另一个窗口(观察者)的底部。后者不是应用程序内的窗口。
此时,我通过获取窗口的 hWnd 并在线程中定期查询观察到的窗口的位置,相应地移动观察者窗口来解决。
然而,这是一个非常不优雅的解决方案。我想做的是监听被观察窗口的调整大小事件,以便观察者仅在必要时做出反应。
我认为我应该使用钩子,并且我发现了很多方法来做到这一点,但是我对 C WinAPI 的缺乏知识阻碍了我理解我需要创建哪个钩子以及如何创建(pinvoke/参数/等)。
我很确定这是非常微不足道的,并且一些熟悉 C/C++ 和 WinAPI 的人会手头有答案;)
谢谢
I am implementing a small application (observer) that needs to "attach" itself to the bottom of another window (observed). The latter is not a window inside the application.
At this moment I solved by getting the hWnd of the window and querying periodically in a thread the location of the observed window, moving the observer window accordingly.
However this is a very inelegant solution. What I would like to do is to listen to the resize event of the observed window so that the observer will react only when necessary.
I assume I should use a hook, and I found plenty of ways of doing it, but my lack of knowledge of the C WinAPI is blocking me in understanding which hook I need to create and how (pinvoke/parameters/etc).
I'm pretty sure this is quite trivial, and some of you familiar with C/C++ and WinAPI will have the answer ready at hand ;)
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
扩展 Chris Taylor 的答案:您可以使用 ManagedWinApi,而不是自己进行本机互操作,其中包含
钩子
类。编辑:使用 ManagedWinApi。代码中的某个位置:
对于回调,请参考 CallWndProc 和 CWPSTRUCT:
Expanding on Chris Taylor's answer: Instead of doing the native interop yourself, you can use ManagedWinApi, which contains a
Hook
class.EDIT: To use ManagedWinApi. Somewhere in your code:
For the callback, reference CallWndProc and CWPSTRUCT:
我在使用的一些代码中遇到了同样的问题,并发现我无法将托管 .DLL 注入到进程中。
由于不想编写使用 SetWindowsHook 的 C++ 非托管 DLL,我结合使用了
SetWinEventHook
,它在窗口开始和结束移动事件时发出信号,并使用Timer
进行轮询窗口移动时使其看起来跟随窗口移动。这是一个可以做到这一点的类的(非常简化的)版本(只需用移动窗口或引发事件的代码替换 TODO)。
I ran into the same thing in some code I was working with and discovered I couldn't inject a managed .DLL into the process.
Not wanting to write a C++ unmanaged DLL that used SetWindowsHook, I went with a combination of
SetWinEventHook
, which signals when a window starts and ends a move event and aTimer
to poll the window while it's moving to give it the appearance of following the window while it moves.Here's a (very simplified) version of a class that can do that (just replace the TODO's with code to move the window or raise an event).
WH_CALLWNDPROC
hook 可能就足够了,这将允许您监视发往感兴趣窗口的所有消息。您是否询问如何使用 C# 创建全局钩子,或者您是否乐意在 C++ 中创建钩子,然后与 .NET 中的钩子进行互操作?第二个选择是我要走的路线。
基本上我的头脑中,我要做的是以下
1- 在 C 中创建全局钩子,并将函数导出到
InstallHook
和UninstallHook
,可以从使用 Interop 的 C# 应用程序。 InstallHook 获取 C# 应用程序中窗口的 hwnd。2- 当您感兴趣的消息(例如您的案例中的
WM_SIZE
)时,让已安装的钩子函数将自定义消息发布到调用InstallHook
中提供的 C# 窗口。3- 在 C# 应用程序中,从挂钩接收发布消息的窗口将覆盖 WndProc 来处理自定义消息。
这是一种方法的概述。
A
WH_CALLWNDPROC
hook would probably suffice, this will allow you to monitor all messages destined for the window of interest.Are you asking how to create a global hook using C# or are you happy to create the hook in C++ and then interop with that from .NET? The second option is the route I would go.
Basically off the top of my head, what I would do is the following
1- Create global hook in C, and export functions to
InstallHook
andUninstallHook
, which can be called from your C# app using Interop. InstallHook take an hwnd of the window in your C# application.2- Have the installed hook function post a custom message to the C# window provided in the call to
InstallHook
when ever there is a message you are interested in likeWM_SIZE
in your case.3- In the C# application your window that receives the posted messages from the hook will override WndProc to handle the custom message.
That is an outline of one approach.
我建议您使用 WinEvents:
另请参阅:事件挂钩
I suggest you use WinEvents:
See also:event hooks