编写CBT Hook DLL拦截窗口调整大小 如何正确指定lParam参数
CBT钩子拦截窗口调整大小的正确实现
参数解析
当CBTProc的nCode为HCBT_MOVESIZE时,两个参数的含义为:
wParam:待调整/移动的窗口句柄(HWND类型)lParam:指向RECT结构体的指针,存储了系统即将为窗口设置的最终位置与尺寸
拦截逻辑
对于HCBT_MOVESIZE类型的通知,直接返回1即可拦截本次调整大小/移动操作,返回0则允许操作:
- 若需要完全拦截所有调整大小+移动操作,匹配到
HCBT_MOVESIZE后直接返回1即可 - 若需要仅拦截调整大小、允许窗口移动:先读取原窗口尺寸,与
lParam指向的RECT对比宽高是否发生变化,宽高变化时返回1拦截即可 - 若需要不拦截但固定窗口尺寸:直接修改
lParam指向的RECT的宽高为固定值,再返回0即可
修正后的示例代码
#include "pch.h" #include <Windows.h> extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc( _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam ) { if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam); switch(nCode) { case HCBT_MOVESIZE: // 窗口即将被移动或调整大小 // 场景1:完全拦截所有调整大小+移动操作,直接返回1 // return 1; // 场景2:仅拦截调整大小,允许移动 RECT oldRect; GetWindowRect((HWND)wParam, &oldRect); RECT* newRect = (RECT*)lParam; int oldWidth = oldRect.right - oldRect.left; int oldHeight = oldRect.bottom - oldRect.top; int newWidth = newRect->right - newRect->left; int newHeight = newRect->bottom - newRect->top; if (oldWidth != newWidth || oldHeight != newHeight) { // 宽高发生变化,属于调整大小操作,拦截 return 1; } // 宽高未变,属于移动操作,放行 return 0; // 场景3:不拦截,但固定窗口大小为800x600 // RECT* targetRect = (RECT*)lParam; // targetRect->right = targetRect->left + 800; // targetRect->bottom = targetRect->top + 600; // return 0; } return CallNextHookEx(nullptr, nCode, wParam, lParam); }
注意事项
你原有代码中使用LOWORD(lParam)匹配EVENT_SYSTEM_MOVESIZESTART的逻辑是错误的,EVENT_SYSTEM_MOVESIZESTART属于WinEventHook的事件ID,不适用于CBT钩子的参数解析,直接删除该段逻辑即可。
内容的提问来源于stack exchange,提问作者user14761342
相关产品推荐
相关产品推荐

