windows.h -> Anwendung schließt sich nicht ordnungsgemäß -> ich behandle zwei Windows gleichzeitig



  • Kannst du mir bitte erläutern was "Eine Message Bumb pro Message Queue" bedeutet ?
    Ich habe die Begriffe mal gegoogled, verstehe den Hintergrund aber nicht genau



  • Eine Message Pump (oder Message Loop) ist das Verarbeiten der Nachrichten einer Message Queue. Zumindest der Haupthread einer Windows-Anwendung besitzt eine Message Queue, über die das Verhalten der Anwendung und der zugehörigen Fenster gesteuert wird. Diese Message Queue wird durch Benutzerinteraktion (Tastatur, Maus) oder mit vom System erzeugten Nachrichten automatisch befüllt, dazu musst du als Anwender nichts programmieren. Aber um Nachrichten aus der Queue zu entfernen und zu bearbeiten brauchst du eine Message Pump (oder Loop), die oft so aussieht:

    MSG message;
    while( GetMessage( &message, nullptr , 0, 0 ) )
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
    

    Wenn du dir die Doku zu GetMessage ansiehst wirst du sehen, dass nicht alle Situationen abdeckt und der Codeblock richtigerweise so aussehen sollte:

    MSG message;
    while( BOOL success = (GetMessage( &msg, nullptr, 0, 0 ) > 0) )
    { 
       if( success )
       {
          TranslateMessage( &msg ); 
          DispatchMessag( &msg ); 
       }
       else
       {
          // Fehler bei GetMessage oder WM_QUIT empfangen
       }
    }
    

    Wenn du für das Fensterhandle nullptr einsetzt werden alle Nachrichten der Message Queue bearbeitet.

    MSDN Doku zu GetMessage
    MSDN Doku zu Message Queues



  • Das hat mir sehr geholfen. Dank des Tipps mit dem nullptr, funktioniert es super. Danke dir.

    • Nun werden allerdings beide Fenster geschlossen, sobald ich eins schließe, da WM_DESTROY ja für beide Windows gleich gilt. Ich bin mir nicht sicher, aber nun kann ich die Windows ja nicht mehr unterscheiden und unabhängig schließen, oder ?

    Nutze ich aber nicht den nullptr, sondern das WindowHandle, kann ich wiederum nur ein Fenster mit der Message Pump behandeln.. und dadurch ist das Fenster, welches ich nicht mit der Message Pump abarbeite, gefreezed



  • Die MSG Struktur hat ein Feld hwnd, damit kannst du prüfen, ob die Nachricht für dein Fenster bestimmt war oder nicht.

    Ich hab schon ewig nicht mehr sowas von Hand programmiert, bin mir jetzt auch nicht sicher, wie man sowas sauber löst. Du könntest dein Hauptfenster das Infofenster schließen lassen, das könnte auch funktionieren:

        case WM_QUIT:
            DestroyWindow( hInfoWindow );
            HInfoWindow = nullptr;
            ...
            break;
    

    Dazu müsste das hInfoWindow wieder eine globale Variable sein. Ist wohl doch etwas kniffliger, als gedacht.



  • This post is deleted!


  • In den Nachrichtenbehandlungsfunktionen überprüfst du einfach, ob der HWND Parameter mit dem HWND Wert der Nachricht übereinstimmt.



  • @TKuehn Du musst natürlich nicht PostQuitMessage bei beiden Fenstern ausfrufen. Bei dem Info-Fenster würde sich anbieten, dieses mit DestroyWindow zu zerstören.
    Oder man könnte dieses Fenster nur einmal erzeugen und dann nur per ShowWindow ein oder ausblenden (ausblenden dann natürlich als Reaktion im WM_CLOSE-Zweig).
    Typischerweise würde man für einen Infodialog auch kein vollwertiges Fenster erzeugen sondern eben - naja eben einen Dialog.
    Dein GetMessage sollte als HWND auch nullptr (oder NULL) übergeben. Bei einem ungültigen Handle kann GetMessage -1 (obwohl BOOL) zurückliefern. Das wurde vor Jahrzehnten mal geändert und dient eigentlich als gutes Beispiel, dass es nicht immer eine gute Idee ist, nachträglich noch Dinge bei so fundamentalen Sachen zu ändern.



  • @DocShow: Deine Abfrage auf success ist aber falsch (da bei dir -1 auch als erfolgreich angesehen wird).
    Daher auch in der Doku die explizite Abfrage auf -1 bzw. andersherum:

    if ( success > 0)
    

    Oder wenn man auch im Fehlerfall die Schleife beenden will:

    while( GetMessage( &msg, hWnd, 0, 0 ) > 0)
    


  • @Th69
    Autsch, ja.



  • @yahendrik Ohja, danke. Ich wusste nicht, dass es an dem PostQuitMessage(0) liegt.
    Nun funktioniert es, wie ich es mir vorgestellt habe 🙂
    Danke an alle Antworten!


Log in to reply