Basic window creation
我在处理Windows窗口时遇到了问题,尽管我以前曾经这样做过,而且工作正常。在阅读了有关此问题的最常见建议之后,它仍然存在。有人可以告诉我为什么输入处理被破坏了吗?
预期行为:
观察到的行为:
- 可拖动窗口,直到第一个"进入循环" -MessageBox关闭,然后将其固定
- 在第一个MessageBox之后,全天显示Windows10的蓝色小"忙碌"圆圈
结论:消息处理已损坏。
我不知道为什么...
系统:
- Windows 10版本1803(内部版本17134.81),64位
VS 2017 Community Edition的编译器:
-
vcvarsall.bat amd64
-
cl -MTd -nologo -FC -Zi -W4 -WX -wd4100 -wd4312 FirstTry.cpp / link User32.lib Gdi32.lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include"windows.h" static bool bAppIsRunning = false; static bool bMessageAlreadyShown = false; LRESULT CALLBACK win_MainWNDCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam){ LRESULT result = 0; switch(msg){ case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP:{ WPARAM vKeyCode = wParam; bool bWasDown = ((lParam & (1 << 30)) != 0); bool bIsDown = ((lParam & (1 << 31)) == 0); if (bWasDown != bIsDown) { switch (vKeyCode) { case VK_ESCAPE:{ bAppIsRunning = false; }break; default:{ result = DefWindowProc(wnd,msg,wParam,lParam); }break; } } }break; default:{ result = DefWindowProc(wnd,msg,wParam,lParam); }break; } return result; } int CALLBACK WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR LpCmdLine, int NCmdShow){ WNDCLASSA wndCLass = {}; wndCLass.style = CS_HREDRAW | CS_VREDRAW; wndCLass.lpfnWndProc = win_MainWNDCallback; wndCLass.hInstance = HInstance; wndCLass.lpszClassName = (LPCSTR)"WindowClass"; if(RegisterClassA(&wndCLass)){ HWND wnd = CreateWindowExA( 0, wndCLass.lpszClassName, (LPCSTR)"FirstTry", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1240, 720, 0, 0, HInstance, 0); if(wnd){ bAppIsRunning = true; HDC DeviceContext = GetDC(wnd); PatBlt(DeviceContext, 0, 0, 1240, 720, BLACKNESS); ReleaseDC(wnd, DeviceContext); while(bAppIsRunning){ if(!bMessageAlreadyShown){ MessageBoxA(NULL, (LPCSTR)"Successfully entered loop.", (LPCSTR)"Success!", MB_ICONINFORMATION | MB_OK); bMessageAlreadyShown = true; } MSG msg; while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)){ switch(msg.message){ case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP:{ WPARAM vKeyCode = msg.wParam; bool bWasDown = ((msg.lParam & (1<<30)) != 0); bool bIsDown = ((msg.lParam & (1<<31)) != 0); if(bIsDown != bWasDown){ switch(vKeyCode){ case 'W':{ bMessageAlreadyShown = false; }break; default:{ TranslateMessage(&msg); DispatchMessageA(&msg); }break; } } } } } } MessageBoxA(NULL, (LPCSTR)"Closing Application.", (LPCSTR)"Bye bye!", MB_ICONINFORMATION | MB_OK); } } return ERROR_SUCCESS; } |
代码的主要问题是,仅在收到某些按键消息时才调用
您还使用了基于
尝试类似这样的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include <windows.h> static bool bMessageAlreadyShown = false; LRESULT CALLBACK win_MainWNDCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: { WPARAM vKeyCode = wParam; bool bWasDown = ((lParam & (1 << 30)) != 0); bool bIsDown = ((lParam & (1 << 31)) == 0); if (bWasDown != bIsDown) { switch (vKeyCode) { case 'W': case VK_ESCAPE: DestroyWindow(wnd); return 0; } } break; } case WM_ERASEBKGND: PatBlt((HDC)wParam, 0, 0, 1240, 720, BLACKNESS); return 0; } return DefWindowProc(wnd, msg, wParam, lParam);; } int CALLBACK WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPSTR LpCmdLine, int NCmdShow) { WNDCLASS wndCLass = {}; wndCLass.style = CS_HREDRAW | CS_VREDRAW; wndCLass.lpfnWndProc = win_MainWNDCallback; wndCLass.hInstance = HInstance; wndCLass.lpszClassName = TEXT("WindowClass"); if (RegisterClass(&wndCLass)) { HWND wnd = CreateWindowEx( 0, wndCLass.lpszClassName, TEXT("FirstTry"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1240, 720, 0, 0, HInstance, 0); if (wnd) { MSG msg; while (GetMessage(&msg, 0, 0, 0)) { if (!bMessageAlreadyShown) { bMessageAlreadyShown = true; MessageBox(NULL, TEXT("Successfully entered loop."), TEXT("Success!"), MB_ICONINFORMATION | MB_OK); } TranslateMessage(&msg); DispatchMessage(&msg); } } } MessageBox(NULL, TEXT("Closing Application."), TEXT("Bye bye!"), MB_ICONINFORMATION | MB_OK); return ERROR_SUCCESS; } |
请注意,我删除了
我还删除了ALT-F4的处理,因为操作系统会自动为您处理。它关闭窗口,触发
我还添加了