这是我基于win32 api的代码的摘录:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void __fastcall TMyThread::Execute(void)
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WindowProc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = class_name.c_str();
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
return;
}
hwnd = CreateWindowEx(0, class_name.c_str(), NULL, 0, 0, 0, 100, 100, HWND_MESSAGE, NULL, wc.hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
return;
}
MSG msg;
BOOL ret;
while ((ret = GetMessage(&msg, 0, 0, 0)) != 0)
{
if (ret != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
我的问题:
退出消息循环后是否需要进行一些资源清理(比如CloseHandle)?我经常看到代码示例没有任何这样的东西。这是正确的吗?
新创建的窗口是否可以在第一次调用GetMessage函数之前将消息接收到线程队列中(我们假设该窗口已成功创建,即函数CreateWindowEx返回没有错误)?
请注意,TMyThread不是应用程序的主线程。因此,它可以在一次应用程序运行中多次创建和销毁。请不要注意非常简化的窗口创建。此特定窗口并不意味着在屏幕上可见。它的创建仅用于接收来自其他应用程序的消息。调用CreateWindowEx函数时,使用hWndParent参数的HWND_MESSAGE值突出显示。
答案 0 :(得分:1)
通过在上面的例子中反复创建,运行和销毁线程,我发现从消息循环中退出后需要调用两个方法。首先是 DestroyWindow ,其次是 UnregisterClass 。在用户确认他确实要关闭应用程序之后,在WM_CLOSE处理程序中的常规应用程序 DestroyWindow 函数should be called中。 DestroyWindow 函数然后将WM_DESTROY和WM_NCDESTROY消息发送到窗口。响应WM_DESTROY消息,应用程序应调用 PostQuitMessage(0)函数,该函数会立即退出消息循环。所以这部分代码在所有场景中都不是必需的。我需要显式调用 DestroyWindow 函数,因为我只是通过发送WM_QUIT消息来退出消息循环。如果不这样做,有时我在尝试取消注册窗口类时收到错误1412(ERROR_CLASS_HAS_WINDOWS)。
if (hwnd != NULL)
{
ret = DestroyWindow(hwnd);
if (ret == 0)
{
str.printf(L"Window destroying failed (GetLastError = %d)!", GetLastError());
ShowError(str);
}
hwnd = NULL;
}
ret = UnregisterClass(class_name.c_str(), wc.hInstance);
if (ret == 0)
{
str.printf(L"Window class unregistration failed (GetLastError = %d)!", GetLastError());
ShowError(str);
}
答案 1 :(得分:0)
您必须非常小心Win32中的资源。确保您仔细查看了文档,以确定Windows本身将为您卸载的内容以及您必须自行卸载的内容。
例如,当HWND
被破坏时,HWND
将被销毁。
最好的办法是尝试卸载您个人创建的所有内容。如果在卸载时从特定函数返回错误,则可能不应卸载它,因为它已被Windows或某些相关资源卸载。
重要的是不要在没有必要时卸载东西,因为这可能会导致崩溃。
因此,例如,使用直接来自资源的窗口创建的图标可能不应被卸载。但是,您创建的HBITMAP
创建的绘制到其他窗口,绝对应该卸载。
您的部分问题可以通过使用断点的快速测试来确定。我不知道我的头脑。