我无法使全局系统挂钩工作.我想尽可能早地在窗口移动时收到通知,并更改窗口大小.这意味着CBT挂钩HCBT_MOVESIZE
不会切割它,它只会在窗口移动后发生.我想挂钩窗口的实际移动,并能够在移动过程中更改窗口大小.
钩子是从DLL设置的,回调函数在该DLL中.这就是我尝试过的.
WH_CALLWNDPROC
.移动窗口时会发出警报(WM_MOVING
从其他应用程序收到窗口),但我无法更改消息的内容.WH_CALLWNDPROCRET
与...相同WH_CALLWNDPROC
.HCBT_MOVESIZE
.事件发生得很晚.WH_GETMESSAGE
.永远不会收到WM_MOVE
,WM_MOVING
或WM_WINDOWPOSCHANGING
.这个钩子允许我改变消息.更新:Windows事件挂钩似乎允许我捕获它:
hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc,
0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
Run Code Online (Sandbox Code Playgroud)
但是,这会产生一个不同的问题:更改窗口大小使用SetWindowPos()
不起作用(它会改变大小,但会立即更改回以前的大小),即使我使用了SWP_NOSENDCHANGING
.想法?
更新2:子类似乎可行,但是每个程序运行后Visual Studio崩溃(许多其他窗口也是如此).如果我放置断点并遍历"unsubclassing",它会很好用,但是当我让程序自行运行时却不行.想法?
我有一个CBT钩子(它来自前面),每当HCBT_ACTIVATE
发送一个新窗口,我删除任何以前的子类使用SetWindowLongPtr()
(这也必须在64位上运行),然后子类化新窗口.如果我在任何地方放置断点,并在断开时立即恢复会话,一切正常.但是,当我没有任何断点时,Visual Studio会在程序退出时崩溃.
嗯,我认为 HCBT_MOVESIZE 正是您想要的,因为 MSDN 是这样描述 CBT 挂钩的:
系统在激活、创建、销毁之前调用该函数, 最小化、最大化、移动窗口或调整窗口大小。
特别是:
HCBT_MOVESIZE 即将移动窗口或调整窗口大小。
(这些引述摘自http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx)
...所以我认为您及时收到了 HCBT_MOVESIZE 调用。处理 HCBT_MOVESIZE 的钩子函数也允许返回一个整数,以便系统可以确定是否允许或应该阻止该操作。因此,考虑到 HCBT_MOVESIZE 挂钩应该有一个选项来阻止该操作,我想说它是在移动事件发生之前调用的。
您真的确定在移动事件之后调用钩子函数吗?如果您在钩子函数中对特定句柄执行 GetWindowRect 调用,则返回的矩形是否等于传递给钩子函数的矩形?