如何调用SetWindowPos仅调整菜单栏下方区域至400x400?
解决方法
SetWindowPos操作的是整个窗口的尺寸,包含标题栏、菜单栏这些非客户区域,所以直接设置400x400会让实际可绘图的客户区被菜单栏等占用一部分,达不到目标大小。下面给两种可行方案:
方案1:反推窗口总尺寸保证客户区大小
通过AdjustWindowRectEx函数,根据你需要的400x400客户区大小,自动计算出包含非客户区的窗口总尺寸,再用SetWindowPos设置,就能确保菜单栏下方的客户区刚好是400x400。
具体代码:
// 定义目标客户区大小(宽400,高400) RECT clientTarget = {0, 0, 400, 400}; RECT windowRect = clientTarget; // 根据窗口风格、是否有菜单,计算窗口总尺寸 AdjustWindowRectEx( &windowRect, GetWindowLongPtr(hWnd, GWL_STYLE), // 获取主窗口风格 TRUE, // 窗口包含菜单栏,设为TRUE GetWindowLongPtr(hWnd, GWL_EXSTYLE) // 获取主窗口扩展风格 ); // 设置窗口大小 SetWindowPos( hWnd, NULL, 0, 0, windowRect.right - windowRect.left, // 计算窗口宽度 windowRect.bottom - windowRect.top, // 计算窗口高度 SWP_NOMOVE | SWP_NOZORDER );
方案2:创建独立子窗口作为绘图区
如果不想调整主窗口大小,更直观的方式是在主窗口客户区中创建一个专门的子窗口,固定大小为400x400,放在菜单栏下方,所有绘图操作都在这个子窗口中进行。
步骤1:获取菜单栏高度
MENUBARINFO menuInfo = {sizeof(MENUBARINFO)}; GetMenuBarInfo(hWnd, OBJID_MENU, 0, &menuInfo); int menuHeight = menuInfo.rcBar.bottom - menuInfo.rcBar.top;
步骤2:创建绘图子窗口
先注册一个自定义窗口类(用于处理绘图消息):
WNDCLASSEX wc = {0}; wc.cbSize = sizeof(WNDCLASSEX); wc.lpfnWndProc = DrawSubWndProc; // 自定义的子窗口消息处理函数 wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = L"DrawSubWindow"; RegisterClassEx(&wc);
然后创建子窗口:
HWND hDrawWnd = CreateWindowEx( 0, L"DrawSubWindow", L"", WS_CHILD | WS_VISIBLE | WS_BORDER, // 带边框方便查看范围 0, menuHeight, // 位置从菜单栏下方开始 400, 400, // 目标大小 hWnd, NULL, GetModuleHandle(NULL), NULL );
步骤3:子窗口绘图逻辑
在DrawSubWndProc中处理WM_PAINT消息:
LRESULT CALLBACK DrawSubWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // 在这里执行绘图操作,比如画一个红框 Rectangle(hdc, 0, 0, 400, 400); EndPaint(hWnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, msg, wParam, lParam); } }
内容的提问来源于stack exchange,提问作者peter.petrov
相关产品推荐
相关产品推荐

