Win32窗口调整大小时粘住鼠标无法正常缩放问题求助
你代码中存在多个语法和逻辑错误,直接导致窗口缩放时卡死:
- 消息循环缺失获取消息的逻辑:现有循环没有调用
GetMessage/PeekMessage从消息队列拉取消息,所有窗口事件都无法正常处理,必然导致界面卡死。 - 大小写不匹配:窗口过程定义为
WindowProc,但wWinMain中给lpfnWndProc赋值的是小写开头的windowProc,存在拼写错误。 WM_SIZING消息参数使用错误:该消息的lParam是指向待调整窗口矩形RECT的指针,不是直接存储宽高的数值,直接用LOWDORD/HIWORD读取宽高完全错误。- 错误调用
SetWindowPos触发死循环:在WM_SIZE、WM_SIZING中调用SetWindowPos会再次触发WM_SIZE消息,形成无限递归调用,直接导致UI线程卡死,就是你说的「粘住鼠标」的现象。 - 常量拼写错误:
SWPNOZORDER应为SWP_NOZORDER,缺少下划线。 - 宽高比计算逻辑不完整:你只处理了宽度小于4:3比例的情况,没有覆盖高度过小的场景。
如果你要固定窗口4:3的宽高比,不需要调用SetWindowPos,直接修改WM_SIZING传入的RECT参数即可,不需要处理WM_SIZE消息来限制比例,修正后的完整代码如下:
#include <windows.h> #include <string> LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_SIZING: { // 从lParam拿到窗口矩形指针 RECT* pRect = (RECT*)lParam; LONG width = pRect->right - pRect->left; LONG height = pRect->bottom - pRect->top; // 固定4:3宽高比 const float aspectRatio = 800.0f / 600.0f; // 判断用户正在拖动的边缘,调整对应边 if (width / (float)height > aspectRatio) { // 宽度太大,按比例调整高度 LONG newHeight = (LONG)(width / aspectRatio); if (wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT) { pRect->top = pRect->bottom - newHeight; } else { pRect->bottom = pRect->top + newHeight; } } else { // 高度太大,按比例调整宽度 LONG newWidth = (LONG)(height * aspectRatio); if (wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT) { pRect->left = pRect->right - newWidth; } else { pRect->right = pRect->left + newWidth; } } // 处理WM_SIZING返回TRUE表示我们已经修改了矩形参数 return TRUE; } case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } } int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow) { WNDCLASSEX wnd = {0}; wnd.lpszClassName = L"WindowLearn"; wnd.hInstance = hInstance; wnd.lpfnWndProc = WindowProc; wnd.cbSize = sizeof(WNDCLASSEX); wnd.style = CS_HREDRAW | CS_VREDRAW; wnd.hCursor = LoadCursor(NULL, IDC_ARROW); // 补上默认光标,避免窗口内鼠标样式异常 RegisterClassEx(&wnd); HWND hWnd = CreateWindowEx(NULL, L"WindowLearn", L"WindowLearnChild", WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 800, 600, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg = {0}; // 修正消息循环,添加GetMessage逻辑 while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; }
内容的提问来源于stack exchange,提问作者sandeep p
相关产品推荐
相关产品推荐

