在打开窗口之前,我想计算窗口的完整大小。我使用AdjustWindowRectEx()来实现这一点。对于一个客户端大小为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()打开窗口并传递参数
wrect.right - wrect.left
wrect.bottom - wrect.top
随着窗口大小的改变,窗口的物理尺寸实际上是656x515像素。然而,GetWindowRect()返回646x505,即与AdjustWindowRectEx()返回的相同尺寸,但正如我所说,当我在桌面上拍摄屏幕截图并使用绘画程序测量窗口的大小时,它的物理尺寸实际上是656x515像素。有人能解释一下吗?
客户端大小没问题,是640x480,但看起来边框大小计算错误,因为边框使用的像素比AdjustWindowRectEx()和GetWindowRect()计算的多。
我使用的是Windows 7。
编辑:
这个问题被downvote了,是因为问题的标题有误导吗?如MSDN autodocs中所述,WS_OVERLAPPED不受AdjustWindowRectEx()支持。那么有没有其他方法可以计算WS_OVERLAPPED窗口的尺寸?使用WS_OVERLAPPEDWINDOW不是一个解决方案,因为它设置了WS_THICKFRAME和WS_MAXIMIZEBOX,而我不想要这些。
现在有一些测试代码,展示了这个问题。您可以看到客户端大小很好,但窗口的物理大小比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;
}