1

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

     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 ......有没有办法解决这个问题?

4

1 回答 1

2

GetMessage()如果没有窗口,则不返回 FALSE。它只是在调用线程的消息队列中查找消息。您正在NULL为其hWnd参数指定,因此它不会关心消息如何排队,无论是按PostMessage()窗口还是按PostThreadMessage()线程 ID。

每个线程都有自己的本地消息队列,因此需要自己的消息循环。在主线程开始其消息循环后,您当然可以在工作线程中创建一个新窗口。它们彼此独立。因此,您在主线程中遇到的任何问题都与在工作线程中创建窗口无关。其他事情正在发生。

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

  1. -1如果发生错误
  2. 如果WM_QUIT检索到消息,则为0
  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); 
    }
}
于 2013-06-20T00:39:09.280 回答