You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:36:00