Frage

Ich habe zwei Codedateien, einer enthält meine WinMain() Funktion und alle Funktionen, die sich auf mein Hauptdialogfenster beziehen. Der andere enthält einen Thread -Rückruf und eine variable Funktionen, die sich auf mein Programm beziehen. Ich habe definiert HWND hWnd = NULL als globale Variable in MainDLg.cpp und definiert extern HWND hWnd in anderen.cpp (der den Thread -Rückruf enthält). Der Thread wird erstellt, wenn der WM_INITDIALOG Nachricht wird an das Fenster gesendet. Innerhalb des Thread -Rückrufs, das hWnd Variable ist null, bis der lange Betrieb durchgeführt wird, und danach wird sie verfügbar.

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;
}

Other.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;
}

Beide Nachrichtenfelder in der ListenThread Rückrufe werden angezeigt, wenn die Anwendung gestartet wird. Kann mir bitte jemand sagen, warum das passiert? Gibt es etwas, das ich tun kann, um dies zu reparieren, außerdem zu tun, außer zu tun? while( hWnd == NULL ); Zu Beginn meiner ListenThread ?

War es hilfreich?

Lösung

Das WM_INITDIALOG Nachricht tritt auf Vor CreateDialog kehrt zurück und hWnd ist nicht eingestellt, bis CreateDialog kehrt zurück. Daher beginnt der Thread zu läufen, bevor das CreateDialog zurückkehrt und die globale festlegt hWnd Variable.

Sie können dies also beheben, indem Sie Ihre Thread -Kreation von der verschieben WM_INITDIALOG Nachricht an kurz nach der Rückkehr von CreateDialog.

Sie müssen dies jedoch nicht tun, da Ihr Code das globale nicht benötigt hWnd Variable. Sie übergeben bereits Ihr Dialog -Fenster -Handle als Parameter an die Thread -Startvorgangsvorgang. Also werfen Sie einfach das LPVParam auf eine HWND und benutze das. Dadurch können Sie Ihre globale Variable loswerden, was eine schlechte Praxis ist.

Other.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;
}

Andere Tipps

Das WM_INITDIALOG Nachricht wird an ausgegeben WndProc() von innen von CreateDialog() selbst nicht durch DispatchMessage(). Dies ist genauso viel in der CreateDialog() Dokumentation. Dein hWnd Variable wird erst nachher zugewiesen CreateDialog() Ausgänge. Wenn Ihr Thread vor dem Laufen beginnt, bevor CreateDialog() beendet (abhängig von der Aufgabenplanung, das ist keine Garantie), Ihre erste MessageBox() wird angerufen. Während MessageBox() läuft, CreateDialog() hat Zeit zum Beenden und Zuweisen der Variablen, weshalb der zweite der zweite ist MessageBox() wird angerufen, nachdem Sie den ersten entlassen haben MessageBox().

Sie müssen die nicht verwenden hWnd Variable in Ihrem Thread überhaupt. Sie bestehen den Dialog HWND zum lpParameter Parameter von CreateThread(), so wird es in der erscheinen lpvParam Parameter von ListenThread(), z.B:

DWORD WINAPI ListenThread( LPVOID lpvParam )  
{  
    HWND hWnd = (HWND) lpvParam;  
    ...
    return 0;  
}  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top