Aufruf von MoveWindow () mit bRepaint auf TRUE gesetzt

8

Das Folgende stammt aus dem Abschnitt "Bemerkungen" von MoveWindow() Dokumentation:

  

Wenn der Parameter bRepaint TRUE ist, sendet das System den WM_PAINT   Nachricht an die Fensterprozedur unmittelbar nach dem Verschieben des Fensters   (Das heißt, die MoveWindow-Funktion ruft die UpdateWindow-Funktion auf).

Also habe ich angenommen, dass, wenn ich MoveWindow() mit bRepaint auf TRUE setze, die Fensterprozedur sofort aufgerufen wird und eine WM_PAINT Nachricht übergibt, aber das ist was meine Tests zeigen:

  • Wenn MoveWindow() aufgerufen wird, wird die Fensterprozedur aufgerufen sofort, aber eine Nachricht WM_ERASEBKGND wird an sie übergeben und nicht a WM_PAINT message .
  • Die Region ist immer noch ungültig. Wenn ich also zur Nachrichtenschleife zurückkehre und keine Nachrichten in der Nachrichtenwarteschlange sind, wird eine Nachricht WM_PAINT gesendet.

Habe ich die Dokumentation falsch interpretiert?

Hinweis: Ich spreche davon, die Methode MoveWindow() für das übergeordnete Fensterobjekt aufzurufen.

Bearbeiten:

Das ist mein Testcode:

%Vor%     
Trevor Sullivan 09.10.2015, 22:34
quelle

4 Antworten

6
  

Habe ich die Dokumentation falsch interpretiert?

Grundsätzlich ja. Sie haben eine kleine Tatsache über MSDN-Dokumentation zu winapi-Funktionen entdeckt, die sehr, sehr wichtig zu wissen ist. Es ist nicht als Tutorial geschrieben. Es setzt ein grundlegendes Verständnis davon voraus, wie der winapi funktioniert, die Art von Wissen, die man durch das Lesen von Petzolds "Programming Windows" -Buch erhält.

Dieses Buch kann Ihnen beibringen, dass der Windows-Malzyklus immer WM_ERASEBKGND enthält. Also wird der Hintergrund zuerst gemalt, was auch immer du mit WM_PAINT als nächstes drauf machst.

Mehrere Gründe, warum solche Implementierungsdetails in der MSDN-Dokumentation übersprungen werden. Zunächst einmal gibt es eine Menge davon und alles inklusive macht es nur schwer durch den Artikel zu pflügen. Als nächstes ist es ziemlich ungewöhnlich, tatsächlich einen Nachrichtenhandler für WM_ERASEBKGND zu schreiben. Sie geben normalerweise einfach an DefWindowProc () weiter. Das verwendet den WNDCLASSEX.hbrBackground, den Sie auswählten, 99% der Zeit gut genug, um die Arbeit zu erledigen. Beachten Sie, dass Ihr Fenster vermasselt aussieht, weil Sie das nicht getan haben. Da Sie einen Message-Handler geschrieben haben, ist es jetzt Ihre Aufgabe, sich darum zu kümmern. Einfach zu tun, rufen Sie einfach DefWindowProc () selbst.

Schließlich werden in der MSDN-Dokumentation Details weggelassen, da es sehr schwierig ist, die Funktionsweise von Windows zu verbessern. Es gibt ein weiteres Implementierungsdetail, das Sie in Ihrem Testprogramm sehen können. Wenn MoveWindow mit bPaint = TRUE aufgerufen wird, zeichnet nicht überhaupt etwas. Einfach zu sehen, indem Sie das Fenster verschieben, indem Sie es mit der Titelleiste ziehen, nachdem Sie es zum ersten Mal angeklickt haben. Beachten Sie, dass ein erneutes Klicken das Fenster zurückspringen lässt, aber Sie weder WM_ERASEBKGND noch WM_PAINT erhalten.

Das ist eine Optimierung bei der Arbeit, die Windows besser arbeiten lässt. Und nicht im MSDN-Artikel erwähnt. Wenn das Fenster nicht vom Bildschirm und zurück verschoben wurde und die Größe des Fensters nicht geändert wurde, kann eine Verknüpfung verwendet werden. Es kopiert einfach die Pixel in dem Videobildpuffer von der alten Position zu der neuen Position. Viel effizienter als die App alles neu streichen zu lassen. Wenn Sie mit aktiviertem Aero arbeiten, ist es noch optimaler, es muss die Pixel überhaupt nicht kopieren.

Last but not least, beim Schreiben von Code wie diesem, Windows zu reverse-engineering ist ziemlich lehrreich und empfohlen, müssen Sie nicht. Es ist viel einfacher, das Dienstprogramm Spy ++ zu verwenden.

    
Hans Passant 14.10.2015 07:34
quelle
2

Was wahrscheinlich passiert, ist, dass MoveWindow WM_ERASEBKGND mit SendMessage sendet (was den WndProc Callback sofort aufruft und auf seine Verarbeitung wartet), aber WM_PAINT via PostMessage (was nur die Nachricht setzt in der Warteschlange, so wird es nach dem Schlafen verarbeitet werden, wenn DispatchMessage aufgerufen wird).

Ich weiß nicht, ob es nur ein Test ist oder ob Sie etwas verarbeiten, nachdem Sie MoveWindow verwendet haben, was die Nachrichtenwarteschlange blockiert. Wenn ja, sollten Sie diese Arbeit in einen anderen Thread verschieben!

Ich hoffe, es hilft.

    
cdonts 10.10.2015 22:32
quelle
1
  

Habe ich die Dokumentation falsch interpretiert?

Ja und nein.

Nein - die Dokumentation ist ziemlich klar.

Ja - wie Hans Passant sagte, Sie können sich nicht auf solche Details von MSDN verlassen.

Es gibt viele WinAPI-Funktionen, die "gotchas", undokumentiertes Verhalten oder erwarteten Zustand der Umgebung (inkl. Timing) und dergleichen haben. Es könnte sein, dass es sich wie in einigen Windows-Versionen verhält. Vielleicht tut es das unter bestimmten Umständen immer noch.

In der Praxis wird MS viele Anwendungen testen, um zu sehen, ob sie nach einer solchen Änderung funktionieren. Da Sie das WM_PAINT in der Regel "wenn es passiert" verarbeiten und nur malen, ist es in diesem Fall einfach zu sehen, wie sich diese Änderung in den meisten Anwendungen nicht auf das Endbenutzerergebnis auswirkt.

Nehmen Sie also MSDN immer als "allgemeine Beschreibung". Verwenden Sie Ihre eigenen Tests und andere Quellen, um die tatsächlichen Verhaltensdetails zu erhalten. Sei froh, dass du mit der Windows-API arbeitest, wenn du jemals weniger genutzte APIs verwendest, wirst du viel schlechter dran sein (ich litt sehr unter den USB / HID-bezogenen APIs).

    
srdjan.veljkovic 14.10.2015 23:55
quelle
1

Ich wollte den bereitgestellten Testcode von Rony nicht überschreiben, also entschied ich mich, meine Alternative zu posten, was meiner Meinung nach besser geeignet ist, Windows Message zu debuggen, die einzige Voraussetzung, externe Tools zum Anzeigen der Debug-Nachricht DebugView . Dies kann natürlich durch eine Listbox ersetzt werden, wenn jemand möchte.

%Vor%     
milevyo 19.10.2015 15:55
quelle

Tags und Links