Problem mit SetMouseHook
-
@Mechanics sagte in Problem mit SetMouseHook:
Nein, es wird direkt deine WndProc aufgerufen, ohne den Umweg über die Message Queue.
Nein
EDIT: Bzw. "ja", da du es denke ich auf den SendMessage Teil bezogen hast. War etwas verwirrt weil @CUser1 schon falsch verstanden hat wie WM_PAINT funktioniert.@CUser1 sagte in Problem mit SetMouseHook:
@hustbaer Was heißt dann direkt bearbeiten? Das wie du sagst bei WM_PAINT Windows das Window einfach redrawed, ohne das der Thread bzw. dessen WndProc des Fensters überhaupt etwas mitbekommt?
Ebenfalls nein
WM_PAINT wird niemals in die Queue gestellt aber es wird auch nicht direkt die WndProc aufgerufen.
GetMessage
tut nur einfach so als wäre ganz hinten in der Queue ein WM_PAINT gewesen wenn die Paint-Region nicht leer ist.Also das läuft (grob skizziert, sinngemäss) eher so:
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) { start: if (checkMessageQueue(hWnd, wMsgFilterMin, wMsgFilterMax)) { // ... "Echte" Message aus der Queue holen, lpMsg befüllen etc. ... if (lpMsg->msg == WM_QUIT) return FALSE; else return TRUE; } if (WM_PAINT >= wMsgFilterMin && WM_PAINT <= wMsgFilterMax) { if (!isPaintRegionEmpty(hWnd)) { // Wir tun einfach so als wäre in der Queue noch eine WM_PAINT Nachricht gewesen lpMsg->msg = WM_PAINT; // ... return TRUE; } } // ... // Keine Message da => warten waitForNewMessageOrTimerOrPaintRegionChange(hWnd); goto start; }
-
ps: Das erklärt auch warum
WM_PAINT
Messages immer und immer wieder reported werden, bis man endlichBeginPaint
/EndPaint
aufruft.Die MS Doku sagt dazu
GetMessage does not remove
WM_PAINT
messages from the queue. The messages remain in the queue until processed.Stimmt bloss nicht. Es sieht bloss so aus als ob sie nicht entfernt würden, weil sie in Wirklichkeit gar nie reinkommen sondern bei Bedarf einfach aus dem Nichts erzeugt werden.
-
@CUser1 Und zu dem Teil:
Für "SendMessage": Wenn die Nachricht für den aktuellen Thread bestimmt ist, dann wird sie direkt bearbeitet ohne sie in die Message-Queue einzufügen.
Damit meine ich das was @Mechanics beschrieben hat: in dem Fall wird die WndProc direkt aufgerufen.
-
@hustbaer Wenn ich es richtig verstehe dann "erzeugt" GetMessage die WM_PAINT oder WM_TIMER nicht aus dem Messagequeue sondern durch die Abfrage anderer Bedingungen, was MartinRichter mit direkt gemeint hat, weil dass nicht über den Queue läuft.
Aber trotzdem muss man PeekMessage oder GetMessage callen weil sonst bleibt das WM_PAINT trotzdem aus.
-
@hustbaer Ja dann meint direkt aber bloß, dass sie anderen Messages "vorgezogen" wird? Und nicht wie ein Treiber der die CPU schlagartig unterbricht?
-
@CUser1 sagte in Problem mit SetMouseHook:
@hustbaer Wenn ich es richtig verstehe dann "erzeugt" GetMessage die WM_PAINT oder WM_TIMER nicht aus dem Messagequeue sondern durch die Abfrage anderer Bedingungen, was MartinRichter mit direkt gemeint hat, weil dass nicht über den Queue läuft.
Aber trotzdem muss man PeekMessage oder GetMessage callen weil sonst bleibt das WM_PAINT trotzdem aus.
Ja, das hast du richtig verstanden.
Bei
SendMessage
an ein Fenster des eigenen Threads läuft das aber anders. Weil warten bis der eigene Thread (der ja gerade inSendMessage
hängt) irgendwann malPeekMessage
/GetMessage
aufruft -- da könnte man lange warten. In dem Fall muss Windows also die WndProc direkt aufrufen.Und nicht wie ein Treiber der die CPU schlagartig unterbricht?
Schlagartig unterbrochen wird dabei aber auch nichts. Dein Thread hat ja
SendMessage(eigenesFenster)
aufgerufen. Und in dem Fall ruftSendMessage
dann einfach direkt die WndProc auf.
-
@hustbaer Wenn man SendMessage an einen anderen Thread sendet und Windows dann die WndProc aufruft dann bräuchte man ja Critical Section damit nicht Windows und der eigene Thread ggf. zugleich Werte verändern?
-
@CUser1 sagte in Problem mit SetMouseHook:
@hustbaer Wenn man SendMessage an einen anderen Thread sendet und Windows dann die WndProc aufruft dann bräuchte man ja Critical Section damit nicht Windows und der eigene Thread ggf. zugleich Werte verändern?
Wenn du
SendMessage
an ein Fenster eines anderen Threads machst, dann geht das ganz normal über die Queue. Also "fast ganz normal". Solche Messages werden bevorzugt behandelt, und ich bin mir nicht sicher ob in dem Fall nicht auchGetMessage
/PeekMessage
im "Ziel-Thread" direkt die WndProc aufruft. Aber der "Ziel-Thread" muss auf jeden Fall erstmal eine "Message-Processing" Funktion aufrufen (alsoGetMessage
,PeekMessage
und noch ein paar andere).
-
@hustbaer Ja es ergibt eh alles Sinn wenn man mit den Begriffen "schlagartig unterbrechen" oder "direkt" konform umgeht.
-
@CUser1 sagte in Problem mit SetMouseHook:
@hustbaer Wenn man SendMessage an einen anderen Thread sendet und Windows dann die WndProc aufruft dann bräuchte man ja Critical Section damit nicht Windows und der eigene Thread ggf. zugleich Werte verändern?
Nein. Da es der eigene Thread ist, würde das sowieso nichts nutzen.
Also:Wenn Du SendMessage aufrufst und ein anderer Thread ist involviert, dann blockiert Dein Thread so lange bis SendMessage zurück kommt. Punkt.
Ein Thread wird eine Nachricht von einem anderen Thread nur entgegen nehmen, wenn Peek-,GetMessage aufgerufen wird. Und nur wenn der Thead mit return aus der WindowProc zurückkehr, läuft der sendende Thread weiter.
Bei COM wird es spaßiger. Da kann ein externer Aufruf von einem STA Aufruf tatsächlich reentrant sein und ein eingehender COM Aufruf oder eine Nachricht kann wären einem simplen Aufruf in der eigenen Anwendung etwas verändern...
-
@Martin-Richter Das mit COM habe ich nicht verstanden?
Bei COM erstellt man ja einen Pointer und die COM Funktion erzeugt ein Objekt und der Pointer zeigt dann dorthin oder?
Ist das nicht wie bei FILE * f = fopen(...); da wird diese struct auch wo anders erstellt durch die mrsvc80.dll oder so?
Verwenden die da malloc um solche aobjekte zu erzeugen?
Oder wo werden die COM Objekte erzeugt?
Und wo ist der Messagequeue? Hustbär sagte der ist nicht im virtuellen Speicher des Prozesses wo der Thread ist?
-
@CUser1 sagte in Problem mit SetMouseHook:
Und wo ist der Messagequeue? Hustbär sagte der ist nicht im virtuellen Speicher des Prozesses wo der Thread ist?
Nein, das hab ich nicht gesagt. Ich habe gesagt (geschrieben) dass diese Beschreibung falsch ist:
Also schreibt Windows die Messages der Reihe nach in den VRAM des Prozesses wo der Thread ist der Messages verwendet, an eine Stelle wo grade Platz ist?
-
@hustbaer Und wie ist es dann?
-
@CUser1 Die genauen Details sind soweit ich weiss nicht dokumentiert.
Ist aber auch egal, das Verhalten der Queue ist ausreichend gut dokumentiert dass man damit arbeiten kann.