Reputation: 450
I'm learning DX12 and, in the process, learning "good old Win32". i have trouble exiting the main loop and it seems related to the fact that i'm not receiving the WM_CLOSE message.
In C++, Windows 10, Console application.
#include <iostream>
#include <d3d12.h>
#include <dxgi1_4.h>
#include <tchar.h>
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
int main()
{
std::cout << "Hello World!\n";
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
CS_CLASSDC,
WndProc,
0L, 0L,
GetModuleHandle(NULL),
NULL, NULL, NULL, NULL,
_T("ker engine"),
NULL
};
std::cout << "Registering Class\n";
::RegisterClassEx(&wc);
std::cout << "Creating Window\n";
HWND hwnd = ::CreateWindow(
wc.lpszClassName,
_T("Ker Engine DX12"),
WS_OVERLAPPEDWINDOW,
100, 100, 1280, 800, NULL, NULL,
wc.hInstance, NULL
);
std::cout << "Show Window\n";
::ShowWindow(hwnd, SW_SHOWDEFAULT);
std::cout << "Update Window\n";
::UpdateWindow(hwnd);
std::cout << "Entering main loop\n";
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != (WM_QUIT))
{
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
std::cout << msg.message << std::endl;
switch (msg.message)
{
case WM_CLOSE:
std::cout << "close received\n";
::PostQuitMessage(0);
break;
}
continue;
}
}
std::cout << "leaving main loop\n";
std::cout << "Destroy Window\n";
::DestroyWindow(hwnd);
std::cout << "Unregister Class\n";
::UnregisterClass(wc.lpszClassName, wc.hInstance);
std::cout << "Bye\n";
return 0;
}
When i press the X (close) red window button, the window is closed but :
The output is :
Entering main loop
[a lot of message code, in decimal]
160 (a lot of it) (WM_NCMOUSEMOVE)
161 (WM_NCLBUTTONDOWN)
275 (WM_TIMER)
no more output printed, i have to close the console manually.
no WM_CLOSE,or WM_DESTROY, or WM_QUIT. Between BUTTONDOW and whatever TIMER is supposed to be, there should be an event related to the fact that the windows was closed, doesn't it ?
I'm a beginner at this. I tried to search google and stackoverflow but i didn't understand if the context applied to me, or it was too specific/unrelated. it's probably a duplicate but i can't find it.
Am i losing/skiping message perhaps ? that's all i can think of.
Upvotes: 1
Views: 1258
Reputation: 450
Thanks to Simon Mourier comment and link to a tutorial, the problem was solved.
The message handling had to be done in WndProc, not in the "main loop".
I'm reposting the modified, cleaned, working, code :
#include <iostream>
#include <d3d12.h>
#include <dxgi1_4.h>
#include <tchar.h>
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
std::cout << "close received\n";
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
int main()
{
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
CS_CLASSDC,
WndProc,
0L, 0L,
GetModuleHandle(NULL),
NULL, NULL, NULL, NULL,
_T("ker engine"),
NULL
};
::RegisterClassEx(&wc);
HWND hwnd = ::CreateWindow(
wc.lpszClassName,
_T("Ker Engine DX12"),
WS_OVERLAPPEDWINDOW,
100, 100, 1280, 800, NULL, NULL,
wc.hInstance, NULL
);
::ShowWindow(hwnd, SW_SHOWDEFAULT);
::UpdateWindow(hwnd);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != (WM_QUIT))
{
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
::DestroyWindow(hwnd);
::UnregisterClass(wc.lpszClassName, wc.hInstance);
return 0;
}
Upvotes: 1