c++在新线程中创建窗口

c++ creating a window in a new thread

本文关键字:创建 窗口 线程 新线程 c++      更新时间:2023-10-16

我有一个基本的窗口程序,问题是当我尝试在消息循环已经开始后在新线程中创建一个窗口时,窗口显示一秒钟并消失。有人知道原因吗?可以在单独的线程中创建窗口吗?

     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…有办法绕过这个吗?

如果没有窗口,

GetMessage()不会返回FALSE。它只在调用线程的消息队列中查找消息。您为其hWnd参数指定NULL,因此它不会关心消息如何排队,是否由PostMessage()到窗口,或由PostThreadMessage()到线程的ID。

每个线程都有自己的本地消息队列,因此需要自己的消息循环。在主线程启动其消息循环之后,可以在工作线程中创建一个新窗口。它们彼此独立。因此,无论您在主线程中遇到什么问题,都与在工作线程中创建窗口无关。

话虽如此,请记住GetMessage()返回BOOL,这实际上是int,而不是真正的boolGetMessage()可以返回3个不同的返回值之一:

  1. -1如果发生错误
  2. 0如果检索到WM_QUIT消息
  3. >0如果检索到任何其他消息

您只检查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); 
    }
}