Mehrfaches Öffnen von MessageBox verhindern.



  • hmm... peinlich peinlich.. ich weiss nicht genau was ein Thread bzw. Mutex ist. 😕
    Nach etwas googlen glaube ich allerdings nicht, dass ich damit arbeite, zumindest nicht bewusst.
    Ich probiere mich weiter an der BoolVariable Variante aber welche Infos braucht ihr, um mir evtl. doch weiterhelfen zu können?
    Grober Aufbau des Programms?
    Danke für bisherige Infos.



  • probier dies (ungetestet):

    int SingleMessageBox (HWND h, LPCTSTR text, LPCTSTR capt, UINT type)
    {
        static volatile LONG lock;
        volatile int res;
        if (InterlockedIncrement(&lock) == 1)
            res = MessageBox (h, text, capt, type);
        else
            res = -1; // irgendein wert, der bedeutet, dass keine msgbox erzeugt wurde
        InterlockedDecrement (&lock);
        return res;
    }
    

    🙂



  • @CStoll: Du Tier. So läufts natürlich! Vielen Dank!!
    Aber warum soll ich Mutex verwenden und keine BoolVariable?

    @Undertaker: Code wird getestet. Vielen Dank!

    Einfach ein Top-Forum!



  • Mackie1980 schrieb:

    hmm... peinlich peinlich.. ich weiss nicht genau was ein Thread bzw. Mutex ist. 😕
    Nach etwas googlen glaube ich allerdings nicht, dass ich damit arbeite, zumindest nicht bewusst.

    Wenn du nicht weißt, was du machst, hast du ein Problem 😃 Wie genau sieht denn deine gesamte Nachrichtenverarbeitung aus?

    Zur Erklärung: MessageBox() blockiert normalerweise den Thread, von dem aus es aufgerufen wurde, bis du die MB wieder geschlossen hast. Deshalb können die weiteren auftauchenden MB's nur aus anderen Threads kommen.

    Mackie1980 schrieb:

    @CStoll: Du Tier. So läufts natürlich! Vielen Dank!!
    Aber warum soll ich Mutex verwenden und keine BoolVariable?

    Die einzelnen Threads müssen natürlich sich gegenseitig synchronisieren, um nicht durcheinanderzukommen (es darf immer nur ein Thread gleichzeitig auf die Variable zugreifen - und natürlich sollte zwischen dem if() und der anschließenden Zuweisung auch niemand dazwischenfunken), also brauchen sie einen Mutex, um den Zugriff zu regeln. Und damit hast du den Mutex, der deine bool-Variable sichert, die wiederum die MessageBox()-Aufrufe steuert - da ersparen wir uns doch die Variable und sichern mit dem Mutex direkt die MessageBox.



  • CStoll schrieb:

    Zur Erklärung: MessageBox() blockiert normalerweise den Thread, von dem aus es aufgerufen wurde, bis du die MB wieder geschlossen hast. Deshalb können die weiteren auftauchenden MB's nur aus anderen Threads kommen.

    ich glaube bei WM_TIMER messages kann das auch passieren (vielleicht wenn HWND 0 ist, oder so)...
    🙂



  • Nein, bei normalen Nachrichten kann das nicht passieren - die Windows Nachrichtenbehandlung ist sequentiell, d.h. erst wenn eine Nachricht fertig ist, wird die nächste angestoßen (und WM_TIMER wird nichtmal durchgelassen, wenn noch andere Nachrichten warten).



  • CStoll schrieb:

    Nein, bei normalen Nachrichten kann das nicht passieren - die Windows Nachrichtenbehandlung ist sequentiell, d.h. erst wenn eine Nachricht fertig ist, wird die nächste angestoßen (und WM_TIMER wird nichtmal durchgelassen, wenn noch andere Nachrichten warten).

    sollte eigentlich so sein, ist aber nicht so. 😉
    ich hab's gerade ausprobiert, ein mfc-dialogbasiertes programm, in die OnInitDialog ein: SetTimer (1, 1000, 0); und den timer-handler so:

    void CTimertestDlg::OnTimer(UINT nIDEvent) 
    {
        ::MessageBox (0, "hallo", "doof", MB_OK);
    	CDialog::OnTimer(nIDEvent);
    }
    

    das gibt jede sekunde eine neue msgbox, die liegen zwar übereinander, aber wenn du sie verschiebst, siehst du die anderen.
    🙂



  • Wenn man sich auf einen Thread beschränkt braucht man garkeine Synchronisierung.
    Wenn man mehrere Threads verwendet wäre es IMO besser eine Thread-Lokale Variable zu verwenden.



  • hustbaer schrieb:

    Wenn man mehrere Threads verwendet wäre es IMO besser eine Thread-Lokale Variable zu verwenden.

    Und was nützt eine thread-lokale Variable, wenn man Probleme mit der Zusammenarbeit mehrerer Threads hat 😉



  • CStoll schrieb:

    hustbaer schrieb:

    Wenn man mehrere Threads verwendet wäre es IMO besser eine Thread-Lokale Variable zu verwenden.

    Und was nützt eine thread-lokale Variable, wenn man Probleme mit der Zusammenarbeit mehrerer Threads hat 😉

    ???
    Eine thread-lokale Variable ganz einfach deswegen, damit nicht ein Thread eine Message-Box eines anderen Threads blockiert. Die könnte aus einem ganz anderen Grund angezeigt werden - wäre IMO nicht gut die dem User einfach vorzuenthalten.

    Und: für den Zugriff auf eine thread-lokale Variable muss man eben nix synchronisieren, da jeder Thread hübsch seine eigene Kopie bekommt.



  • CStoll schrieb:

    Nein, bei normalen Nachrichten kann das nicht passieren - die Windows Nachrichtenbehandlung ist sequentiell, d.h. erst wenn eine Nachricht fertig ist, wird die nächste angestoßen (und WM_TIMER wird nichtmal durchgelassen, wenn noch andere Nachrichten warten).

    Das ist nicht richtig.
    Probier es aus, Code der das entsprechende Verhalten zeigt wurde gepostet.
    Der Knackpunkt hierbei ist dass es unter Windows kein "haben fertig bearbeitet" gibt für eine Message, d.h. Windows kann garnicht wissen wann eine WM_XYZ fertig abgearbeitet ist. Daher werden auch feste neue WM_TIMER (oder sonstwas) gepostet wenn keine NEUEN Nachrichten mehr in der Queue stehen, obwohl die zuletzt abgeholte noch nichtmal fertig abgearbeitet wurde.



  • @WM_TIMER: OK, ihr habt mich überzeugt. Aber ich war bisher davon ausgegangen, daß es im Programm eine zentrale Nachrichtenschleife gibt, die nacheinander Nachrichten entgegennimmt und die dazugehörigen Handler aufruft (und dann wartet, bis der Handler fertig ist, bevor sie weitermacht).

    @Synchronisation: Nein, mit dem Ansatz sollten nicht alle irgendwo entstehenden MessageBoxen blockiert werden, sondern nur "meine" (bzw. die MB's, die dem Anwender mitteilen wollen, daß das Senden schiefgegangen ist) - und die können durchaus thread-übergreifend auftreten.
    (aber Mackie hat uns ja immer noch nicht verraten, wie sein Programm zusammenarbeitet - also ist alles weitere reine Spekulation)


Anmelden zum Antworten