我有一个基本的窗口程序,问题是当我尝试在新的线程中创建一个窗口后,消息循环已经启动窗口显示一秒钟并消失。有没有人没有这个原因?可以在单独的线程中创建窗口吗?
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
::hInstance =hInstance; // initialize global variables
::nCmdShow =nCmdShow;
// start thread
HANDLE threadHandle = startThread(StartUp);
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
::CloseHandle(threadHandle);
return static_cast<int>(msg.wParam);
}
DWORD WINAPI StartUp(LPVOID lpParam) // new thread runs here
{
//code to create a new window...
}
到目前为止我发现的是GetMessage(&msg, 0, 0, 0)
如果当前线程中没有窗口,则返回false ...有没有办法绕过这个?
答案 0 :(得分:2)
GetMessage()
不会返回FALSE。它只在调用线程的消息队列中查找消息。您为NULL
参数指定了hWnd
,因此它不关心消息如何排队,无论是PostMessage()
到窗口,还是PostThreadMessage()
到线程的ID。
每个线程都有自己的本地消息队列,因此需要自己的消息循环。在主线程启动其消息循环后,您肯定可以在工作线程中创建一个新窗口。它们彼此独立。因此,您在主线程中遇到的任何问题都与在工作线程中创建窗口无关。还有其他事情正在发生。
话虽如此,请注意GetMessage()
会返回BOOL
,实际上是int
,而不是真bool
。 GetMessage()
可以返回 3 不同的返回值之一:
WM_QUIT
消息您只检查0和!= 0,因此如果GetMessage()
在出错时返回-1,则表示您将其视为成功而非失败。甚至MSDN都说不这样做:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936.aspx
因为返回值可以是非零,零或-1,所以请避免使用以下代码:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
-1返回值的可能性意味着此类代码可能导致致命的应用程序错误。相反,使用这样的代码:
BOOL bRet; while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } }