为什么AdjustWindowRect设置的Win32窗口客户区大小不符合预期?
问题原因
- 传入
AdjustWindowRect的窗口样式不全:你当前仅传入了WS_VISIBLE | WS_SYSMENU,缺少窗口实际会带的非客户区核心样式(比如标题栏WS_CAPTION、边框WS_BORDER等)。AdjustWindowRect只会基于你传入的样式计算非客户区占用尺寸,缺少的样式会导致计算出的总窗口大小偏小,实际创建窗口时系统默认附加的样式会占用更多非客户区空间,直接挤压客户区面积。 - 如果你使用了
WS_EX_*开头的扩展窗口样式,普通的AdjustWindowRect不会将扩展样式对应的非客户区尺寸纳入计算,需要改用AdjustWindowRectEx传入扩展样式参数。
修正后代码
UINT WINDOW_WIDTH = 256; UINT WINDOW_HEIGHT = 240; // 补充完整窗口实际使用的所有样式,示例为带标题栏、系统菜单、最小化按钮、不可调整大小的常用样式 DWORD window_styles = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE; DWORD window_ex_styles = 0; // 若用到扩展样式填对应值,无则留0 SetProcessDPIAware(); RECT rect; rect.left = 0; rect.top = 0; rect.right = WINDOW_WIDTH + rect.left; rect.bottom = WINDOW_HEIGHT + rect.top; // 改用AdjustWindowRectEx传入扩展样式,第三个参数TRUE对应窗口带菜单的场景 AdjustWindowRectEx(&rect, window_styles, TRUE, window_ex_styles); HWND hWnd = CreateWindowEx (window_ex_styles, CLASS_NAME, WINDOW_CAPTION, window_styles, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInst, NULL);
额外注意事项
SetProcessDPIAware建议放在程序入口函数最开头执行,避免窗口相关组件初始化后调用导致DPI感知不生效。- 如果后续给窗口新增可调整大小等样式,需要同步更新传入
AdjustWindowRectEx的样式参数,保证计算结果准确。
内容的提问来源于stack exchange,提问作者apersonwithacompiler
相关产品推荐
相关产品推荐

