创建Win32窗口时未定义光标,为何仅悬停边框/标题栏才加载默认光标?
Win32窗口未正确配置光标导致无法正常激活的问题记录
我在尝试用最简代码创建Win32窗口时,发现了一个奇怪的、大概率未被官方收录的行为:如果开发者省略WNDCLASSEX结构体中的光标定义,或是按如下方式定义光标:
WNDCLASSEX wc ... wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
窗口可以正常显示,但除非用户将鼠标悬停在窗口边框或标题栏上,否则窗口始终无法激活。我发现当鼠标位于窗口客户区时,除了应用启动、窗口创建阶段的常规消息外,Windows会持续发送WM_SETCURSOR消息。我此前从未注意到该问题,直到我创建了一个初始无框的窗口,该窗口会持续显示等待光标(旋转圆圈)。该行为可通过以下代码复现,运行代码时请确保窗口创建瞬间光标位于客户区范围内。我在MSDN及其他站点都未找到相关解释,因此分享出来供其他开发者参考。
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { return DefWindowProcW(hwnd, msg, wparam, lparam); } int main(int argc, char** argv) { HINSTANCE hinstance(GetModuleHandleW(0)); WNDCLASSEXW wc({ 0 }); wc.cbSize = sizeof(WNDCLASSEXW); //wc.style = CS_HREDRAW | CS_VREDRAW;// | CS_OWNDC; // 非必要配置 wc.lpszClassName = L"classname"; wc.lpfnWndProc = WndProc; wc.hInstance = hinstance; //wc.hbrBackground = HBRUSH(COLOR_WINDOW + 1); // 非必要配置 //wc.hIcon = LoadIconW(0, IDI_APPLICATION); // 非必要配置 //wc.hIconSm = wc.hIcon; // 非必要配置 //wc.hCursor = LoadCursorW(hinstance, IDC_ARROW); // 该写法会导致窗口无法正常激活 //wc.hCursor = LoadCursorW(0, IDC_ARROW); // 正确写法,可保证窗口正常激活 if (!RegisterClassExW(&wc)) { DWORD err = GetLastError(); return -1; } DWORD style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; HWND handle = CreateWindowExW(0, L"classname", L"Test Window" , style, CW_USEDEFAULT, CW_USEDEFAULT , CW_USEDEFAULT, CW_USEDEFAULT, 0 , (HMENU)0, hinstance, 0); if (!handle) return -1; MSG msg; while (1) { while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return ((int)msg.wParam); TranslateMessage(&msg); DispatchMessageW(&msg); } } return 0; }
内容的提问来源于stack exchange,提问作者JimK
相关产品推荐
相关产品推荐

