我正在使用WIN32 API开发桌面应用程序,我建立了一个父窗口和四个子窗口,将子窗口作为父窗口的一部分而划分出工作区,四个工作区是可以拖拽调整布局的类似Blender一样,我在WM_SIZING消息中计算拖动后工作区的布局,即我使用WindowMove函数完成工作区的调整工作。
现在的问题是,每次WM_SIZING消息的LPRARAM参数中包含了调整后的矩形信息,窗口过程返回后会将LPARAM中的RECT信息设置到子窗口上,我希望仅由我自己处理工作区的调整,即在接受WM_SIZING消息时,我能通过返回什么值或者调用什么函数,使得窗口过程返回后不会用LPARAM参数设置窗口吗?
我不能将LPARAM参数设置为我计算出的工作区大小,因为当工作区调整一格时,由于小数参数的误差,算出来的工作区分布可能没有改变,如果我将LPARAM参数设置为预期的工作区大小,则LPARAM参数将永远不变,这导致我拖动子窗口边框无法调整窗口大小。
win32如何避免WM_SIZING消息返回后改变窗口大小
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
2条回答 默认 最新
关注【以下回答由 GPT 生成】
问题的核心是如何在WM_SIZING消息返回后避免窗口大小的改变,只由自己处理工作区的调整。根据描述,你希望能够拖动子窗口边框来调整工作区的大小,同时避免窗口大小的改变。
答案是在处理WM_SIZING消息时,可以改变窗口的客户区大小而不改变窗口的实际大小。为了实现这个目标,你需要以下步骤:
- 在创建主窗口时,将窗口样式设置为WS_OVERLAPPEDWINDOW,并在样式中设置WS_CLIPCHILDREN。这样可以确保子窗口的绘制区域不会超出父窗口的范围。
// 创建主窗口时设置样式 HWND hWnd = CreateWindowEx( 0, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr );- 在处理WM_SIZING消息时,通过修改lParam中的RECT结构体,调整工作区的大小。可以通过计算来确定工作区的新大小。可以使用MoveWindow函数来调整子窗口的位置和大小。
case WM_SIZING: { RECT* rect = (RECT*)lParam; // 计算新的工作区大小 int newWidth = rect->right - rect->left; int newHeight = rect->bottom - rect->top; // 根据计算结果调整工作区的大小 // ... // 移动子窗口到适当的位置 MoveWindow(hwndChild1, ...); MoveWindow(hwndChild2, ...); MoveWindow(hwndChild3, ...); MoveWindow(hwndChild4, ...); // 返回WVR_REDRAW,指示区域已失效并需要更新 return WVR_REDRAW; }- 在处理WM_PAINT消息时,通过调用ValidateRect函数来更新工作区的显示。这样可以确保工作区的变化被正确地绘制出来。
case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hWnd, &ps); // 绘制工作区内容的代码 // ... EndPaint(hWnd, &ps); return 0; }通过以上步骤,你可以在WM_SIZING消息中自定义工作区的调整,而不改变窗口的实际大小。同时,子窗口的位置和大小会根据计算结果进行调整,并且工作区的变化会正确地被显示出来。
最后,请注意在处理WM_SIZING消息时,避免使用SetWindowPos函数或修改lParam中RECT结构体的其他成员。这样可以确保窗口的大小不会被改变,而只会改变工作区的大小。
希望以上解决方案对你有帮助。如果你有任何进一步的问题,请随时提问。
如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^本回答被题主选为最佳回答 , 对您是否有帮助呢?评论 打赏 举报解决 1无用