Основная проблема с вашим кодом заключается в том, что вы звоните TranslateMessage()
и DispatchMessage()
только при получении определенных сообщений нажатия клавиш.Вам нужно вызывать их в основном цикле сообщений для ВСЕХ сообщений.И вам следует обрабатывать ВСЕ сообщения в вашем обратном вызове WndProc.
Вы также используете API на основе TCHAR
, но неправильно используете типы типов LPCTSTR
.Вместо этого вам нужно использовать макрос TEXT()
при приведении литералов string / char к TCHAR
.
Вместо этого попробуйте что-то вроде этого:
#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;
}
Обратите внимание, что я удалил вашу переменную bAppIsRunning
, так как она стала избыточной после того, как цикл обработки сообщений обработал сообщение WM_QUIT
.
Я также убрал обработку ALT-F4 , поскольку ОС обрабатывает это автоматически.Он закрывает окно, вызывая сообщение WM_CLOSE
.По умолчанию DefWindowProc()
обрабатывает WM_CLOSE
, разрушая окно, которое вызывает сообщение WM_DESTROY
.
Я также добавил обработку для WM_ERASEBKGND
, чтобы нарисовать фон в окне.Рисование извне цикла сообщений является неправильным.Как только окно будет обновлено на экране, все ваши чертежи будут потеряны, поэтому вам придется перерисовывать все в ответ на WM_ERASEBKGND
и WM_PAINT
.