9

我在创建设定大小的客户区时遇到了一些问题。AdjustWindowRect() 无法正常工作,所以我决定尝试手动计算窗口的宽度和高度。

那也不起作用,我想知道为什么,所以我检查了我用来考虑边界等的值。

#include <iostream>
#include <Windows.h>

int main(void)
{
    std::cout << "GetSystemMetrics(SM_CYEDGE) = " << GetSystemMetrics(SM_CYEDGE) << std::endl;
    std::cout << "GetSystemMetrics(SM_CXEDGE) = " << GetSystemMetrics(SM_CXEDGE) << std::endl;
    std::cout << "GetSystemMetrics(SM_CYBORDER) = " << GetSystemMetrics(SM_CYBORDER) << std::endl;
    std::cout << "GetSystemMetrics(SM_CXBORDER) = " << GetSystemMetrics(SM_CXBORDER) << std::endl;
    std::cout << "GetSystemMetrics(SM_CYCAPTION) = " << GetSystemMetrics(SM_CYCAPTION);

    std::cin.get();
}

这给了我:

GetSystemMetrics(SM_CYEDGE) = 2
GetSystemMetrics(SM_CXEDGE) = 2
GetSystemMetrics(SM_CYBORDER) = 1
GetSystemMetrics(SM_CXBORDER) = 1
GetSystemMetrics(SM_CYCAPTION) = 22

我很确定我的窗口边框没有那么薄。我究竟做错了什么?

编辑1:

最初我的窗口使用 WS_OVERLAPPED 样式。由于 AdjustWindowRect 不允许将该样式与它一起使用,因此我构建了我想要的相同类型的窗口:(WS_BORDER | WS_CAPTION | WS_SYSMENU)。这与我在调用 AdjustWindowRect 和 AdjustWindowRectEx 时使用的样式相同(这个样式为 NULL 作为扩展样式,因为我不使用任何样式)。这给了我正确的宽度,但高度缺少几个像素。

RECT rect = { 0, 0, 800, 600};

AdjustWindowRectEx( &rect, (WS_BORDER | WS_CAPTION | WS_SYSMENU), FALSE, NULL);

CreateWindowEx( ..., rect.right - rect.left, rect.bottom - rect.top, ...);

这给了我 800 像素宽的客户区,但只有 582 像素高。

编辑2:

好奇,我使用了 GetClientRect(); 它告诉我宽度是 800,高度是 600。它为什么不能正常显示?


似乎当我画了整个窗户时,一切都被衡量了。原因?我不知道。

也许其他人可以对此有所了解。

4

2 回答 2

25

第一个问题是您使用了错误的指标。您需要使用 SM_CXSIZEFRAME 来获取可调整大小边框的宽度。

第二个问题是 Windows 不会给你正确的值。Aero 上窗口的粗边框是一个严重的 appcompat 问题。Windows 故意谎报窗口矩形和边框大小。为了让旧程序仍能正常工作,它们需要在 CreateWindow() 调用中指定窗口的大小。但这就是框架的大小,包括边框。没有谎言,窗口最终会导致客户区域太小。

要关闭谎言,您必须告诉 Windows 您知道Aero 行为并且不需要被欺骗。项目+属性、链接器、命令行、附加选项框并添加:

/SUBSYSTEM:CONSOLE,6.0

版本 6.0 是 Vista 版本号,是第一个具有 Aero 的 Windows 版本。请注意,当您执行此操作时,您的程序将不再在 XP 上运行。

于 2012-07-29T06:54:33.023 回答
2

您是否尝试过 AdjustWindowRectEx() 而不是 AdjustWindowRect() ?只要您传递正确的样式(和扩展样式),我就没有理由知道它不能正常工作。

于 2012-07-29T03:26:04.233 回答