Neuzeichnen während MessageBox auf Screen
-
Wer sorgt eigentlich dafür, dass mein Fenster neu gezeichnet wird, während mein Programm auf das Beenden einer MessageBox wartet und wie wird das gemacht?
-
Die WM_PAINT Nachricht ist dafür verantwortlich.
Diese Nachricht wird automatisch erzeugt, wenn ein Fenster verdeckt war und wieder sichtbar wird.
Wenn man selbst ein Neuzeichnen möchte, kann man die Funtion InvalidateRect verwenden (RedrawWindow geht auch).
Wenn dies nun auch passieren soll, während eine MessageBox offen ist, dann benötigt man einen Timer, der für einen das Invalidate ausführt.Aber grundsätzlich: Dein Programm zeigt auch keine neue Daten an, wenn es keinen Timer oder anderen Mechanimus hat (der WM_PAINT auslöst) und einfach nur so da steht im Vordergund...
-
Ja, soweit ist das grundsätzlich klar. Mir ging es nur so durch den Kopf, dass mein Programm ja 'steht', während es auf den Rückgabewert der MessageBox wartet, und deshalb keine Nachrichten aus der Messagequeue holen kann. Demnach müsste WM_PAINT via SendMessage vom OS ausgeführt werden und nicht in die Nachrichtenwarteschlange eingereiht werden?
-
Quatsch. MessageBox hat eine eigene Messageloop und die liefert auch Nachtrichten an Deine Fenster aus...
BTW: WM_PAINT ist eine Pseuonachricht, wie auch WM_TIMER die "egentlich" nicht gesendet wird!!!
-
Aber wie kann mein Programm WM_PAINT behandeln, wenn doch MessageBox blockiert?
int testFunk() { Sleep(5000); return 0; } ... int a = testFunk(); a = MessageBox(hwnd, ...);
Während das Programm in testFunk wartet, wird nix neugezeichnet, wenn ich ein anderes Fenster drüberziehe, wenn es jedoch darauf wartet, dass a mit dem Rückgabewert von MessageBox gefüllt wird, wird neugezeichnet.
Im ersten Fall (testFunk) wird neu gezeichnet, wenn testFunk verlassen wird, im Fall der MessageBox wird sofort neu gezeichnet, obwohl doch mein Programm auf die Rückkehr von MessageBox wartet, so wie es vorher auf die Rückkehr von testFunk wartet ...Irgendwie kriege ich da die Fäden nicht zusammen.
-
Warum liest Du nicht?
Martin Richter schrieb:
Quatsch. MessageBox hat eine eigene Messageloop und die liefert auch Nachtrichten an Deine Fenster aus...
-
Ich les das schon, aber offensichtlich verstehe ich nicht, was
"die liefert auch Nachtrichten an Deine Fenster aus"
bedeutet ...
Es bedeutet wohl nicht, dass MessageBox eine Message (WM_PAINT) in die Queue für meine Fenster stellt, denn die würde ja erst abgearbeitet, wenn mein Programm weiterläuft.
Also nochmal:
Mein Programm wartet auf die Rückkehr von MessageBox.
Ich ziehe irgendein anderes Fenster über mein Programmfenster und wieder weg.
Mein Fenster muss neu gezeichnet werden.
Das stellt doch das OS fest (oder irre ich mich schon hier?)
Also muss das OS nun dafür sorgen, dass der case WM_PAINT - Teil in meinem Programm ausgeführt wird.
Also irgendwer muss irgendwie dahin verzweigen.
Mein Programm selbst wird es wohl nicht sein, da es ja auf MessageBox wartet. Und nun sagst Du:
"MessageBox hat eine eigene Messageloop und die liefert auch Nachtrichten an Deine Fenster aus"
Okay, aber weiß MessageBox überhaupt, dass mein Fenster neu gezeichnet werden muss? Und wenn, dann müsste MessageBox doch irgendwie meine für WM_PAINT vorgesehenen Instruktionen ausführen (lassen), also doch via SendMessage?Ich raffs einfach nicht ...
-
Also muss das OS nun dafür sorgen, dass der case WM_PAINT - Teil in meinem Programm ausgeführt wird.
Nein, das macht dein Programm selbst.
Ist halt in der MFC versteckt, aber die ist kein Teil des OS.Irgendwo in der MFC steht sowas in der Art:
void CBlubb::Run() // führt das Programm aus { while (!HabenFertig()) { MSG msg; HolNeNachricht(&msg); VerarbeiteDieNachricht(&msg); } }
Die Funktion VerarbeiteDieNachricht() sorgt dann dafür, dass dein OnPaint() etc. aufgerufen wird.
Und in der MessageBox Funktion steht auch genau so eine Schleife!
Nur dass dortwhile (!HabenFertig())
mitwhile (MessageBoxNochSichtbar())
ersetzt wurde.Probier einfach mal folgendes: erzeuge in einem deiner Fenster einen Timer. Und in OnTimer() zeigst du ne MessageBox() an. Tadaaaaaaaa.... eine Million Message-Boxen.
-
Belli schrieb:
Es bedeutet wohl nicht, dass MessageBox eine Message (WM_PAINT) in die Queue für meine Fenster stellt, denn die würde ja erst abgearbeitet, wenn mein Programm weiterläuft.
Doch es bedeutet genau das.
Dein Programm hat nur eine Queue (genauer Dein Thread), aber jeder Programmteil kann doch PeekMessate/GetMessage/TranslateMessage/DispatchMessage ausführen wann er will.
Genau dasmacht DoModal und genau das mach auch eine MessageBox (die wiederum DoModal aufruft).Belli schrieb:
Also nochmal:
Mein Programm wartet auf die Rückkehr von MessageBox.
Ich ziehe irgendein anderes Fenster über mein Programmfenster und wieder weg.
Mein Fenster muss neu gezeichnet werden.
Das stellt doch das OS fest (oder irre ich mich schon hier?)Jo!
Belli schrieb:
Also muss das OS nun dafür sorgen, dass der case WM_PAINT - Teil in meinem Programm ausgeführt wird.
Jo!
Belli schrieb:
Also irgendwer muss irgendwie dahin verzweigen.
Mein Programm selbst wird es wohl nicht sein, da es ja auf MessageBox wartet.Genau. Undda ein WM_APINT nur erzeugt wird wenn GetMessage/PeekMessage ausgeführt wird kannst Du davon ausgehen, dass MessageBox genau das tut... nämlich auch eine MessageLoop auf der gemensamen Messagequeue ausführen.
Belli schrieb:
Und nun sagst Du:
"MessageBox hat eine eigene Messageloop und die liefert auch Nachtrichten an Deine Fenster aus"
Okay, aber weiß MessageBox überhaupt, dass mein Fenster neu gezeichnet werden muss? Und wenn, dann müsste MessageBox doch irgendwie meine für WM_PAINT vorgesehenen Instruktionen ausführen (lassen), also doch via SendMessage?Nö Das weiß GetMessage!
Belli schrieb:
Ich raffs einfach nicht ...
Mach Dir nix draus, dass ist mehr oder weniger ein temporärer Zustand deren Dauer mehr oder weniger lange andauert...
-
Mhm, vielleicht hab ichs jetzt:
Wenn ich Dich richtig verstehe, holt die MessageLoop der MessageBox (auch) Messages die für mein Fenster bestimmt sind ab - und nicht nur solche die für die MessageBox bestimmt sind, also quasi eine zweite MessageLoop für mein Fenster. WM_PAINT für mein Fenster wird dann dispatched und sozusagen im Kontext der MessageLoop von MessageBox erledigt.MessageBox hat eine eigene Messageloop und die liefert auch Nachtrichten an Deine Fenster aus...
würde also bedeuten, dass MessageBox Nachrichten für mein Fenster überhaupt erst mal abholt und dann dispatched ...
So richtig?
@hustbaer:
MFC ist nicht im Spiel.
-
Okay, GetMessage holt alle Nachrichten aus der Queue für den aufrufenden Thread ab. Da MessageBox im selben Thread läuft, holt die dort implementierte Nachrichtenschleife alles ab und dispatched es ...
Hat eine Weile gedauert, aber nun hab ichs.Danke für Deine/Eure Geduld!