全球拦截窗口移动

Veg*_*sen 6 c++ winapi

我无法使全局系统挂钩工作.我想尽可能早地在窗口移动时收到通知,并更改窗口大小.这意味着CBT挂钩HCBT_MOVESIZE不会切割它,它只会在窗口移动后发生.我想挂钩窗口的实际移动,并能够在移动过程中更改窗口大小.

钩子是从DLL设置的,回调函数在该DLL中.这就是我尝试过的.

  • WH_CALLWNDPROC.移动窗口时会发出警报(WM_MOVING从其他应用程序收到窗口),但我无法更改消息的内容.
  • WH_CALLWNDPROCRET与...相同WH_CALLWNDPROC.
  • CBT挂钩HCBT_MOVESIZE.事件发生得很晚.
  • WH_GETMESSAGE.永远不会收到WM_MOVE,WM_MOVINGWM_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会在程序退出时崩溃.

Fre*_*abe 1

嗯,我认为 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 调用,则返回的矩形是否等于传递给钩子函数的矩形?