16,472
社区成员
我的想法是在将客户区设置成数学里面的那种坐标系(Y向上为正),并且用FrameRect()函数绘制个矩形边框。代码如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static SIZE clientRectSizeInViewport;
static int mapMode = MM_ISOTROPIC;
static SIZE viewportExtSize;
static SIZE windowExtSize = { 2000, 2000 };
static POINT viewportOrgPoint;
static POINT windowOrgPoint = { 0, 0 };
switch (message)
{
case WM_SIZE:
{
clientRectSizeInViewport.cx = GET_X_LPARAM(lParam);
clientRectSizeInViewport.cy = GET_Y_LPARAM(lParam);
viewportExtSize.cx = clientRectSizeInViewport.cx;
viewportExtSize.cy = -clientRectSizeInViewport.cy;
viewportOrgPoint.x = clientRectSizeInViewport.cx / 2;
viewportOrgPoint.y = clientRectSizeInViewport.cy / 2;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowExtEx(hdc, windowExtSize.cx, windowExtSize.cy, nullptr);
SetViewportExtEx(hdc, viewportExtSize.cx, viewportExtSize.cy, nullptr);
SetWindowOrgEx(hdc, windowOrgPoint.x, windowOrgPoint.y, nullptr);
SetViewportOrgEx(hdc, viewportOrgPoint.x, viewportOrgPoint.y, nullptr);
Rectangle(hdc, 100, 100, 200, 200);
RECT rect1;
SetRect(&rect1, 300, 300, 400, 400);
FrameRect(hdc, &rect1, GetStockBrush(GRAY_BRUSH));
RECT rect2;
SetRect(&rect2, 500, 500, 600, 600);
FillRect(hdc, &rect2, GetStockBrush(GRAY_BRUSH));
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
但我发现使用Rectangle()和FillRect()是的绘制时成功的,但FrameRect()函数无法绘制边框。效果如下:
我想问问时怎么回事。谢谢大家哈
猜测 FrameRect 应该用 整个窗口的 DC (GetWindowDC), 而非客户区DC
注释
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowExtEx(hdc, windowExtSize.cx, windowExtSize.cy, nullptr);
SetViewportExtEx(hdc, viewportExtSize.cx, viewportExtSize.cy, nullptr);
SetWindowOrgEx(hdc, windowOrgPoint.x, windowOrgPoint.y, nullptr);
SetViewportOrgEx(hdc, viewportOrgPoint.x, viewportOrgPoint.y, nullptr);
能正常显示3个,我不知道你为什么要加上面这几行