C++ 全局拦截窗口移动
我很难让一个全局系统钩子工作。我希望在窗口移动时尽早收到通知,并更改窗口大小。这意味着CBT hookC++ 全局拦截窗口移动,c++,winapi,C++,Winapi,我很难让一个全局系统钩子工作。我希望在窗口移动时尽早收到通知,并更改窗口大小。这意味着CBT hookHCBT_MOVESIZE不会剪切它,它只在窗口移动后发生。我想钩住窗口的实际移动,并能够在移动过程中更改窗口大小 钩子是从DLL中设置的,回调函数位于该DLL中。这就是我尝试过的 WH_CALLWNDPROC。当窗口移动时(从其他应用程序接收到windows的WM_MOVING),它会提醒我,但我无法更改消息的内容 WH_callwndproct与WH_CALLWNDPROC相同 CBT挂钩
HCBT_MOVESIZE
不会剪切它,它只在窗口移动后发生。我想钩住窗口的实际移动,并能够在移动过程中更改窗口大小
钩子是从DLL中设置的,回调函数位于该DLL中。这就是我尝试过的
。当窗口移动时(从其他应用程序接收到windows的WM_MOVING),它会提醒我,但我无法更改消息的内容WH_CALLWNDPROC
与WH_callwndproct
相同WH_CALLWNDPROC
- CBT挂钩
。事情发生得太晚了HCBT\u MOVESIZE
。切勿接收WH\u GETMESSAGE
、WM\u MOVE
或WM\u MOVING
。这个钩子允许我更改消息WM\u WINDOWPOSCHANGING
hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc,
0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
但是,这会产生一个不同的问题:使用SetWindowPos()
更改窗口大小不起作用(它可以更改大小,但会立即更改回以前的大小),即使我使用SWP\u NOSENDCHANGING
。想法
更新2:子类化似乎可行,但Visual Studio在每次程序运行后都会崩溃(许多其他窗口也是如此)。如果我放置断点并遍历“取消分类”,它会工作得很好,但如果我让程序自己运行,它就不会工作了。想法
我有一个CBT钩子(以前就有了),每当为一个新窗口发送
HCBT_ACTIVATE
时,我都会使用SetWindowLongPtr()
(这也必须在64位上运行)删除以前的子类,然后对新窗口进行子类化。如果我将断点放在任何位置,并在会话中断时立即恢复会话,则一切正常。但是,当我没有任何断点时,Visual Studio会在程序退出时崩溃。Hm,我会认为HCBT_MOVESIZE正是您想要的,因为MSDN对CBT钩子这样说:
The system calls this function before activating, creating, destroying,
minimizing, maximizing, moving, or sizing a window.
系统在激活、创建、销毁,
最小化、最大化、移动或调整窗口大小。
特别是:
HCBT_MOVESIZE
A window is about to be moved or sized.
HCBT_移动大小
窗口即将移动或调整大小。
(这些引文摘自)
…所以我以为你会及时接到HCBT_MOVESIZE电话。处理HCBT_MOVESIZE的hook函数也可以返回一个整数,这样系统就可以确定是允许还是应该阻止该操作。因此,考虑到HCBT_MOVESIZE钩子应该有一个选项来阻止该操作,我认为它是在move事件发生之前调用的
您真的确定在move事件之后调用了hook函数吗?如果对钩子函数中的特定句柄执行GetWindowRect调用,返回的rect是否等于传递给钩子函数的矩形?钩子相当重。你只想在绝对必要的时候使用它们 也就是说,您可以使用其中一个基本挂钩作为进入流程的一种方式。在这个过程中,您可以对感兴趣的窗口进行子类化,并在子类proc中处理大小调整消息,而不是试图在钩子级别捕获所有内容
根据您对调整大小的响应,您可能需要一些进程间通信。使用
HCBT\u MOVESIZE
时,用户可以开始拖动窗口,继续拖动,并且在他释放窗口之前通知不会到达。尽管如此,在技术上移动窗口之前,您还是会收到通知,但它仍然毫无用处。然而,当我没有实际删除子类时,VisualStudio总是崩溃。