AdjustWindowRectEx() 和 GetWindowRect() 使用 WS_OVERLAPPED 给出错误的大小 [英] AdjustWindowRectEx() and GetWindowRect() give wrong size with WS_OVERLAPPED

查看:37
本文介绍了AdjustWindowRectEx() 和 GetWindowRect() 使用 WS_OVERLAPPED 给出错误的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在打开一个窗口之前计算它的完整大小.我正在使用 AdjustWindowRectEx() 来实现这一点.对于客户端大小为 640x480 的窗口,我的代码如下所示:

I want to calculate the full size of a window before opening it. I'm using AdjustWindowRectEx() to achieve this. My code looks like this for a window with a client size of 640x480:

    wrect.left = 0;
    wrect.top = 0;
    wrect.right = 640;
    wrect.bottom = 480;
    AdjustWindowRectEx(&wrect, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, FALSE, 0);

这将返回以下值:

    left: -3
    top: -22
    right: 643
    bottom: 483

但是,当使用 CreateWindowEx() 打开窗口并传递

However, when opening the window using CreateWindowEx() and passing

    wrect.right - wrect.left
    wrect.bottom - wrect.top

作为窗口大小,窗口的物理大小实际上是 656x515 像素.尽管如此,GetWindowRect() 返回 646x505,即与 AdjustWindowRectEx() 返回的尺寸相同,但正如我所说,当我截取桌面的屏幕截图并使用绘图程序测量窗口的大小时,它的物理大小实际上是 656x515 像素.有人对此有解释吗?

as the window size, the window's size physical size actually turns out to be 656x515 pixels. Still, GetWindowRect() returns 646x505, i.e. the same dimensions as returned by AdjustWindowRectEx() but as I said, when I take a screenshot of the desktop and measure the window's size using a paint program, its physical size is actually 656x515 pixels. Does anybody have an explanation for this?

客户端大小没问题,它是 640x480,但看起来边框大小计算错误,因为边框使用的像素比 AdjustWindowRectEx() 和 GetWindowRect() 计算的要多.

The client size is alright, it's 640x480 but it looks like the border size is calculated wrongly because the border uses more pixels than calculated by AdjustWindowRectEx() and GetWindowRect().

我使用的是 Windows 7.

I'm on Windows 7.

这是否是因为问题的标题具有误导性而被否决?正如 MSDN 自动文档中所述,AdjustWindowRectEx() 不支持 WS_OVERLAPPED.那么有没有其他方法可以计算 WS_OVERLAPPED 窗口的尺寸?改用 WS_OVERLAPPEDWINDOW 不是解决方案,因为它设置了我不想要的 WS_THICKFRAME 和 WS_MAXIMIZEBOX.

Is this downvoted because the title of the question is misleading? As stated in the MSDN autodocs, WS_OVERLAPPED is not supported by AdjustWindowRectEx(). So is there any other way to calculate the dimensions of a WS_OVERLAPPED window? Using WS_OVERLAPPEDWINDOW instead is not a solution because it sets the WS_THICKFRAME and WS_MAXIMIZEBOX which I don't want.

这是一些显示问题的测试代码.可以看到客户端大小没问题,但是窗口的物理大小比GetWindowRect()返回的要大.

Here is some test code now which shows the problem. You can see that the client size is alright but the window's physical size is larger than what is returned by GetWindowRect().

#include <stdio.h>

#include <windows.h>

#define CLASSNAME "Test"

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{  
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wcx;
    RECT wrect;
    HWND hWnd;
    char tmpstr[256];

    memset(&wcx, 0, sizeof(WNDCLASSEX));

    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.style = CS_HREDRAW|CS_VREDRAW;  
    wcx.lpfnWndProc = WindowProc;
    wcx.hInstance = hInstance;
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hbrBackground = GetStockObject(BLACK_BRUSH);  // important! otherwise a borderless window resize will not be drawn correctly        
    wcx.lpszClassName = CLASSNAME;

    RegisterClassEx(&wcx);

    wrect.left = 0;
    wrect.top = 0;
    wrect.right = 640;
    wrect.bottom = 480;     
    AdjustWindowRectEx(&wrect, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, FALSE, 0); 

    hWnd = CreateWindowEx(0, CLASSNAME, "Test", WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, 0, 0, wrect.right - wrect.left, wrect.bottom - wrect.top, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, SW_SHOWNORMAL);

    GetWindowRect(hWnd, &wrect);
    sprintf(tmpstr, "%d %d %d %d\n", wrect.left, wrect.top, wrect.right, wrect.bottom);

    AllocConsole();
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), tmpstr, strlen(tmpstr), NULL, NULL);

    GetClientRect(hWnd, &wrect);
    sprintf(tmpstr, "%d %d %d %d\n", wrect.left, wrect.top, wrect.right, wrect.bottom);
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), tmpstr, strlen(tmpstr), NULL, NULL);

    Sleep(10000);

    DestroyWindow(hWnd);        
    UnregisterClass(CLASSNAME, hInstance);          

    return 0;
}   

推荐答案

GetWindowRect api 没有给出正确的大小:

GetWindowRect api doesn't give the correct size:

由于兼容性要求,某些指标的报告方式与启用 Aero Glass(更准确地说,Windows Vista Aero")时屏幕上实际绘制的内容不一致.需要这种方法来改变绝大多数应用程序的系统外观,而这对于大多数应用程序来说不是问题.然而,系统最近发生了一个变化,它将在 Vista RC1 中出现对于与winver = 6.0"链接的可执行文件,从 GetWindowRect() 返回正确的呈现值.这允许新的和新链接的应用程序从 GetWindowRect() 获取正确"的值.

在 Aero Glass 下不可调整大小的窗口上的 GetWindowRect

改为使用 DwmGetWindowAttribute 以获得正确的大小:

Use instead DwmGetWindowAttribute to get the correct size:

DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &wrect, sizeof(wrect));

这篇关于AdjustWindowRectEx() 和 GetWindowRect() 使用 WS_OVERLAPPED 给出错误的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆