【发布时间】:2020-10-14 15:21:25
【问题描述】:
我正在学习 DX12,并在此过程中学习“好老的 Win32”。 我无法退出主循环,这似乎与我没有收到 WM_CLOSE 消息有关。
在 C++、Windows 10、控制台应用程序中。
#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;
}
当我按下 X(关闭)红色窗口按钮时,窗口已关闭,但是:
- 未打印“已关闭收到”
- “离开主循环”没有打印出来。
输出是:
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.
没有 WM_CLOSE、WM_DESTROY 或 WM_QUIT。在 BUTTONDOW 和任何 TIMER 应该是之间,应该有一个与窗户关闭的事实相关的事件,不是吗?
我是这方面的初学者。我试图搜索 google 和 stackoverflow,但我不明白上下文是否适用于我,或者它太具体/不相关。它可能是重复的,但我找不到它。
我可能会丢失/跳过消息吗?我能想到的就这些了。
【问题讨论】:
-
你的程序在做什么?作为用户,您在使用该程序做什么?你在按下窗户关闭按钮吗?请尝试将您的代码简化为minimal reproducible example 并展示给我们。
-
正确的 minimal reproducible example 将是 gist 链接中的代码,但没有注释“链接”到文档或类似的 cmets。此外,强烈建议不要链接到代码。链接可能会消失,或者内容可能会发生变化,从而可能使问题无法回答。问题需要独立。
-
如果你有一个控制台应用程序,你不需要一个消息循环(除非你正在做一些 COM 的东西或其他的东西,也就是:消息与窗口应用程序不同)。如果你有一个窗口应用程序,不要试图重新发明轮子,从这个教程开始:docs.microsoft.com/en-us/windows/win32/learnwin32/…
-
等等,我明白了。我已经有了这个 WndProc 函数。这是我应该将我的 Windows 事件消息处理放在哪里,而不是在循环中,对吧?
-
是的!就是这样!我在 WndProc 中移动了开关,现在它可以工作了。虽然帮助有点复杂,但它确实解决了我的问题。谢谢
标签: c++ windows winapi win32gui