使用 Win32 将 GDI 绘制大小缩放为窗口大小

scaling GDI draw size to window size with Win32

本文关键字:缩放 窗口大小 绘制 Win32 GDI 使用      更新时间:2023-10-16

我正在编写一个 Win32 应用程序,并试图使窗口的大小与我在其中绘制的内容保持一致。作为最简单的情况,我正在尝试创建一个带有绘制矩形的窗口,该矩形正好填充窗口。

CreateWindow(( 的文档说宽度和高度参数以设备单位为单位,而 Rectangle(( 的文档说宽度和高度参数以逻辑坐标为单位,我认为这意味着它们是以逻辑单位测量的。我认为使用我用于创建窗口的长度和宽度设置一个 POINT 结构,通过 DPtoLP(( 传递 POINT,然后使用生成的 x 和 y 值作为矩形的宽度和高度应该有效,但矩形最终大于窗口。事实上,这种差异似乎与我在将窗口尺寸用于矩形之前根本不尝试平移窗口尺寸时完全相同。我哪里出错了?我正在使用的完整测试程序:

POINT logicalUnitSize;
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR    lpCmdLine,
_In_ int       nCmdShow)
{
WNDCLASS wc{};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"Main";
RegisterClass(&wc);
POINT deviceUnitSize{ 200,200 };//width and height of window in device units
HWND hwnd = CreateWindow(wc.lpszClassName, L"Size Test", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, deviceUnitSize.x, deviceUnitSize.y, nullptr, nullptr, hInstance, nullptr);
//get width and height of window in logical units
HDC hdc{ GetDC(hwnd) };
logicalUnitSize = deviceUnitSize;
DPtoLP(hdc, &logicalUnitSize, 1);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc{ BeginPaint(hWnd, &ps) };
Rectangle(hdc, 0, 0, logicalUnitSize.x, logicalUnitSize.y);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

我相信这里的主要问题是要CreateWindow的大小参数适用于非工作区,即包括标题栏和边框等装饰。

创建窗口后使用GetClientRect获取工作区,或使用AdjustWindowRect[Ex]