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

Win32程序启动时WM_SIZE消息返回错误窗口尺寸的原因及解决方法咨询

关于OpenGL窗口初始WM_SIZE尺寸偏差的问题解答

这是Windows窗口开发里挺常见的一个小坑,我来给你捋清楚原因和解决办法:

一、启动时WM_SIZE消息发送的原因

当你调用CreateWindowEx创建窗口后,Windows系统会完成窗口的初始化布局——确定窗口的位置、大小,然后自动给窗口发送WM_SIZE消息,目的是通知你的程序:“窗口尺寸已经确定啦,快更新你的渲染区域和布局!” 这是窗口创建流程里的标准步骤,不管你有没有手动调整窗口,都会触发这一次初始的WM_SIZE。

二、初始尺寸偏差的核心原因

你搞混了窗口整体尺寸和客户区尺寸的区别:

  • 你在CreateWindowEx里传入的1280, 720是整个窗口的大小,包括标题栏、窗口边框这些非客户区部分;
  • 而WM_SIZE消息的lParam返回的是客户区的尺寸——也就是你实际用来绘制OpenGL内容的区域,这部分是要扣除标题栏和边框宽度的。

你看到的1260×677,正好是1280减去左右边框的总宽度、720减去标题栏高度加上上下边框总高度后的结果,完全符合Windows窗口的尺寸计算逻辑。

至于手动调整窗口后尺寸正常,是因为当你拖动窗口时,系统会根据你调整的边界(不管是拖边框还是客户区),重新计算并返回准确的客户区尺寸,这时候你视觉上看到的窗口大小和实际客户区的对应关系是匹配的,所以点击区域就正常了。

三、解决方案

1. 从根源解决:创建时指定客户区尺寸(推荐)

用AdjustWindowRectEx函数,根据你想要的客户区尺寸,反向计算出需要的窗口整体尺寸,再传给CreateWindowEx。这样初始的WM_SIZE返回的客户区就会正好是你要的1280×720。

代码示例:

// 定义你想要的客户区尺寸
RECT desiredClientRect = {0, 0, 1280, 720};
// 根据窗口样式计算所需的整体窗口尺寸
AdjustWindowRectEx(&desiredClientRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_OVERLAPPEDWINDOW);

// 创建窗口,传入计算后的整体尺寸
MainWindow.handle = CreateWindowEx(
    WS_EX_OVERLAPPEDWINDOW,
    windowClass.lpszClassName,
    "Some window",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT,
    desiredClientRect.right - desiredClientRect.left,  // 窗口宽度
    desiredClientRect.bottom - desiredClientRect.top, // 窗口高度
    NULL, NULL, instance, NULL
);

2. 手动发送WM_SIZE消息(不推荐,仅作补充)

如果你暂时不想改窗口创建逻辑,也可以在窗口创建完成后,手动发送一条WM_SIZE消息,强制设置客户区尺寸:

// 窗口创建后调用
SendMessage(MainWindow.handle, WM_SIZE, 0, MAKELPARAM(1280, 720));

但这种方法是“治标不治本”,因为初始的客户区实际尺寸还是小的,只是强制让你的程序用1280×720来渲染,可能会导致渲染内容和实际窗口区域不匹配,还是优先用第一种方法更稳妥。

内容的提问来源于stack exchange,提问作者TopTofu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:57:33