0

我有两个代码文件,一个包含我的WinMain()函数,以及与我的主对话框窗口相关的所有函数。另一个包含与我的程序相关的线程回调和变量函数。我在 MainDlg.cpp 中定义HWND hWnd = NULL为全局变量,并extern HWND hWnd在 Other.cpp 中定义(其中包含线程回调)。当WM_INITDIALOG消息发送到窗口时创建线程。在线程回调中,hWnd变量在执行长操作之前为空,然后变为可用。

MainDlg.cpp

HWND hWnd = NULL;
HANDLE hListenThread = NULL;

DWORD WINAPI ListenThread( LPVOID lpvParam );

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    /* ... */
    if( NULL == (hWnd=CreateDialog( hInstance, MAKEINTRESOURCE(IDD_MAINDLG), NULL, (DLGPROC)WndProc)) )
    {
        MessageBox( NULL, "Error creating the main dialog!", NULL, MB_OK | MB_ICONERROR );
        return -1;
    }

    MSG msg;
    while( GetMessage(&msg,NULL,0,0) && IsWindow(hWnd) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

BOOL CALLBACK WndProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
{

    switch(Message)
    {
        case WM_INITDIALOG:
        {
            DWORD dwListenThreadId = NULL;
            /* referencing hWnd here works fine... */
            /* ... */
            hListenThread = CreateThread(
                NULL,
                0,
                ListenThread,
                hWndDlg,
                0,
                &dwListenThreadId);
            /* ... */
        } break;
    }

    return false;
}

其他.cpp

extern HWND hWnd;
DWORD WINAPI ListenThread( LPVOID lpvParam )
{

    if( hWnd == NULL )
        MessageBox( NULL, "hWnd == NULL", NULL, MB_OK | MB_SYSTEMMODAL );

    if( hWnd != NULL )
        MessageBox( NULL, "hWnd != NULL", NULL, MB_OK | MB_SYSTEMMODAL );

    return 0;
}

ListenThread启动应用程序时会显示回调中的两个消息框。有人可以告诉我为什么会这样吗?除了在我的开头做之外,我还能做些什么来解决这个问题?while( hWnd == NULL );ListenThread

4

2 回答 2

3

WM_INITDIALOG消息在返回之前 CreateDialog出现,并且在返回之前hWnd不会设置CreateDialog。因此线程在 CreateDialog 返回并设置全局hWnd变量之前开始运行。

因此,您可以通过将线程创建从WM_INITDIALOG消息移动到CreateDialog.

但是您不需要这样做,因为您的代码不需要全局hWnd变量。您已经将对话框窗口句柄作为参数传递给线程启动过程。所以只需将 lpvParam 转换为 anHWND并使用它。这会让你摆脱你的全局变量,这是不好的做法。

其他.cpp

DWORD WINAPI ListenThread( LPVOID lpvParam )
{
    HWND hWnd= (HWND)lpvParam;

    if( hWnd == NULL )
        MessageBox( NULL, "hWnd == NULL", NULL, MB_OK | MB_SYSTEMMODAL );

    if( hWnd != NULL )
        MessageBox( NULL, "hWnd != NULL", NULL, MB_OK | MB_SYSTEMMODAL );

    return 0;
}
于 2011-12-02T22:04:54.003 回答
1

消息是从自身内部WM_INITDIALOG发出的,而不是由. 这在文档中已说明。直到退出后才会分配您的变量。如果您的线程在退出之前开始运行(取决于任务调度,这不是保证),您的第一个会被调用。在运行时,有时间退出并分配变量,这就是为什么在您关闭第一个之后调用第二个的原因。WndProc()CreateDialog()DispatchMessage()CreateDialog() hWndCreateDialog()CreateDialog()MessageBox()MessageBox()CreateDialog()MessageBox()MessageBox()

您根本不需要hWnd在线程中使用该变量。您正在将对话框传递HWND给 的lpParameter参数CreateThread(),因此它将出现在 的lpvParam参数中ListenThread(),例如:

DWORD WINAPI ListenThread( LPVOID lpvParam )  
{  
    HWND hWnd = (HWND) lpvParam;  
    ...
    return 0;  
}  
于 2011-12-02T22:05:47.027 回答