Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Paint Message abfangen/Herkunft finden (https://www.delphipraxis.net/159577-paint-message-abfangen-herkunft-finden.html)

ConnorMcLeod 3. Apr 2011 12:33

Paint Message abfangen/Herkunft finden
 
Hallo Kollegen,

vielen Dank erstmal im Nachhinein für all die interessante Lektüre, die ich hier schon finden durfte in den letzten Jahren.

Jetzt habe ich ein (denke ich) Riesenproblem und frage mal so in die Runde:

Wie kann ich herausfinden welche Komponente dafür verantwortlich ist, dass ein WM_PAINT ausgeführt wird?

Habe hier fremden Code und es passiert ein unerwünschtes Zeichnen der Form. Eigentlich ist alles fertiggezeichnet und es wird eine Usereingabe erwartet, aber auf einmal passiert besagtes WM_PAINT.

Der Callstack sagt nur, in welcher Hierarchiefolge das Paint ausgeführt wird, aber nicht von wo die Message herkommt.
Im Messagehandler dito.

Meine Vermutung ist, dass eine der vielen Komponenten auf der Form ein Refresh oder Invalidate o.Ä. veranlasst ... aber welche?

Kann man auch einen Hook für rausgehende Messages machen, die von Delphi an Windows gesendet werden?

Danke für alle Ideen!!
lg Wolfgang
D2010, Win7 Ultimate

PS: AFAIK gibt es keinen Timer.

Uwe Raabe 3. Apr 2011 15:06

AW: Paint Message abfangen/Herkunft finden
 
Das WM_PAINT wird von Windows ausgelöst, wenn es der Meinung ist, daß sich das Control neu zeichnen sollte. Das kann z.B. sein, wenn ein darüberliegendes Fenster wieder gelöscht oder verschoben wird. Das Invalidate bzw. Refresh gibt dem Control nur die Möglichkeit, Windows zu so einem WM_PAINT-Ereignis aufzufordern.

Grundsätzlich sollte ein Control jederzeit in der Lage sein, einen Paint-Befehl zu befolgen. Dein "Riesenproblem" ist meiner Meinung nach also nicht, daß das WM_PAINT auftritt, sondern daß der Code damit nicht klar kommt.

ConnorMcLeod 3. Apr 2011 17:02

AW: Paint Message abfangen/Herkunft finden
 
Servus Uwe,

danke für die flotte Antwort; Du hast Recht, daß Windows selbst die Message sendet, wenn es der Meinung ist ... etc.

In diesem Fall wird mein Fenster erzeugt und gezeigt und damit Ende. Kein anderes Fenster darüber gezeichnet o.Ä. Das Ganze passiert auch innerhalb von Sekundenbruchteilen und ist auf einem superschnellen Rechner vllt gar nicht zu sehen. (Für alle, die sich jetzt denken *Na, und?* sei gesagt, dass beim Zeichnen sehr viel abgefragt wird und das nicht nur Performance kostet, sondern auch logische Fehler produziert).

Es kommt einfach eine zweite WM_PAINT Message daher.
d.h. das Fenster wird gezeichnet, dann nocheinmal. Beim zweitenmal wird es falsch gezeichnet, weil die Logik, die z.B. die Farben berechnet, nicht dafür ausgelegt ist, dass die Berechnung zweimal hintereinander erfolgt (wie gesagt ... nicht mein Code ;-) ).

So, als ob irgendeine andere Komponente noch ein Refresh bzw Repaint hinterherschickt. Das würde nach meinem Verständnis Windows ebenfalls dazu veranlassen, die WM_PAINT an meine Applikation zu schicken.

Lt. Callstack ist es beim zweiten Mal auch ein etwas anderer Aufruf.

Hm. Meine nächste Idee ist, der Reihe nach alle Kompos von der Form zu löschen, solange, bis das Phänomen verschwindet.

Deine Argumente haben mich jetzt dazu bewogen, genau zu prüfen, was der Fokus zwischen den beiden WM_PAINTs macht; kann sein, dass der hin- und herspringt.

Danke und lg, Wolfgang

Bummi 3. Apr 2011 18:19

AW: Paint Message abfangen/Herkunft finden
 
das was Du "painten" möchtest sollte IMHO unabhängig vom Aufruf sein, also gegf. Offscreen malen und im Paint das Resultat darstellen.

ConnorMcLeod 3. Apr 2011 19:10

AW: Paint Message abfangen/Herkunft finden
 
Servus Thomas,

stimmt, so würde ich das in diesem Fall wahrscheinlich auch machen, möchte aber z.Zt. nichts an dem geerbten Code ändern.

Ich weiss, wer malt und ich weiss, wie gemalt wird; ich weiss aber leider nicht, warum gemalt wird ...

Danke trotzdem und lg,
Wolfgang

Uwe Raabe 3. Apr 2011 22:13

AW: Paint Message abfangen/Herkunft finden
 
Selbst wenn du jetzt herausfindest, was das Paint auslöst, hilft dir das nicht viel weiter. Es gibt die unterschiedlichsten Auslöser für ein Paint-Ereignis auf die du überhaupt keinen Einfluss hast. Pack das Problem an der Wurzel und mach die Paint-Methode so, daß sie immer und überall funktioniert. Nur so meine Meinung...

Luckie 4. Apr 2011 01:00

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092772)
Beim zweitenmal wird es falsch gezeichnet, weil die Logik, die z.B. die Farben berechnet, nicht dafür ausgelegt ist, dass die Berechnung zweimal hintereinander erfolgt (wie gesagt ... nicht mein Code ;-) ).

Dann ist entweder dein Konzept falsch oder du benutzt den Code falsch. Wenn du den Code nicht ändern willst, warum auch immer, musst du wohl dein Konzept ändern.

sx2008 4. Apr 2011 01:25

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1092828)
Pack das Problem an der Wurzel...

Richtig! Beim Programmieren rächt sich schlampiges Arbeiten fast immer.
Deshalb nie murksen, sondern immer den sauberen Weg gehen!
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092800)
... möchte aber z.Zt. nichts an dem geerbten Code ändern.

Betrachte es als Verbesserung deiner Fähigkeiten als Programmierer.
Refakturieren und schlechten Code verbessern sollte man häufig üben.

ConnorMcLeod 4. Apr 2011 06:50

AW: Paint Message abfangen/Herkunft finden
 
Hallo Leute,

auch, wenn ich völlig Eurer Meinung bin. Das geht zur Zeit nicht! Es hängt zuviel davon ab, dass es eine zeitlang noch so weiter funktioniert. Am Redesign arbeite ich parallel, und zwar radikal, aber die Umstellung ist erst in ein paar Monaten möglich. Bis dahin muss ich das Ding am Leben erhalten.

Ich habe gefragt, wie schaffe ich *X* und bekomme als Antwort: mach lieber *Y*. Das ist zwar nett gemeint, aber keine wirkliche Hilfe.

Seit der Umstellung (von D7) auf D2010 ist Einiges anders und ein Tail davon beeinflusst scheinbar dieses Verhalten.

Meine Frage: wie kann ich feststellen, von welchem Code das Windows dazu veranlasst wird, ein WM_PAINT zu senden? Gegenbeispiel: ein Hook gibt die Mglkt, von aussen kommende Messages abzufangen. Gibt es so etwas auch für die umgekehrte Richtung?

Trotzdem Danke für Eure Mühe und Zeit,
Wolfgang

Bummi 4. Apr 2011 07:04

AW: Paint Message abfangen/Herkunft finden
 
Die Antwort ist AFAIK einfach nein...
Ob sich Da eine Dialog drübergelegt hatte, ein Resize irgendwo stattgefunden hat, eine der Komponenten ein Paint angefordert hat ...

himitsu 4. Apr 2011 08:39

AW: Paint Message abfangen/Herkunft finden
 
So schwer sollte eine schnelle Änderung nicht sein.
- an der Stelle, wo gezeichnet wird, leitest du alles in ein Bitmap.Canvas um
- ans Ende der Zeichenroutine(n) hängst du noch ein Repaint deiner Anzeige
- ins WM_PAINT/OnRepaint kommt nun nur noch das Ausgeben dieses Bitmaps rein und fertig
= Problem beseitigt und ein mehrfaches Repaint stört nicht mehr, bzw. kaum noch

alfold 4. Apr 2011 11:30

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092710)
...Habe hier fremden Code und es passiert ein unerwünschtes Zeichnen der Form. Eigentlich ist alles fertiggezeichnet und es wird eine Usereingabe erwartet, aber auf einmal passiert besagtes WM_PAINT...

sieht ja so aus als wenn es keine standard Komponente ist! oder wie soll man das verstehen? Eine Form für Usereingaben, da kann ja im allg nicht besonderes als code sein!!??

Zitat:

Zitat von ConnorMcLeod (Beitrag 1092772)
..Es kommt einfach eine zweite WM_PAINT Message daher.
d.h. das Fenster wird gezeichnet, dann nocheinmal. Beim zweitenmal wird es falsch gezeichnet, weil die Logik, die z.B. die Farben berechnet, nicht dafür ausgelegt ist, dass die Berechnung zweimal hintereinander erfolgt (wie gesagt ... nicht mein Code ;-) )...

Kann es sein das da evtl noch ein 'Applikation.Processmessage' drin ist?

Zitat:

Zitat von ConnorMcLeod (Beitrag 1092800)
Ich weiss, wer malt und ich weiss, wie gemalt wird; ich weiss aber leider nicht, warum gemalt wird ...

Gemahlt wird aber nur mit Images oder halt mit graphic Komponenten. Standard Komponenten machen das selbst! Darum wundere ich mich über diese Aussage.

Zitat:

Zitat von ConnorMcLeod (Beitrag 1092847)
..Ich habe gefragt, wie schaffe ich *X* und bekomme als Antwort: mach lieber *Y*. Das ist zwar nett gemeint, aber keine wirkliche Hilfe.

Seit der Umstellung (von D7) auf D2010 ist Einiges anders und ein Tail davon beeinflusst scheinbar dieses Verhalten.

Meine Frage: wie kann ich feststellen, von welchem Code das Windows dazu veranlasst wird, ein WM_PAINT zu senden?

in dem Du mal ein Haltpunkt setzt und dann step by step durch gehst und Dir den Code richtig anschaust!

Ansonsten kann ich Dir nur empfehlen mal 2Bilder an Deinem ersten Post ranzuhängen damit wir sehen was Du meinst! Noch besser ist natürlich der Code für das sogenannte EingabeFenster um das es ja hier geht! Oder treten diese Fehler in Deinem ganzen Projekt auf!?

alfold

ConnorMcLeod 4. Apr 2011 13:02

AW: Paint Message abfangen/Herkunft finden
 
Danke für Euer Mitgefühl ;-)
Ich sehe, dass ich zuwenig Info gegeben habe...

Es handelt sich um ein MDIChild, in dem Labels, DBEdits und DBGrids sind. Alles abgeleitete Versionen mit zusätzlicher firmeneigener Funktionalität. Um das DbGrid geht es und hier passieren kranke Dinge, die leider dzt unumgänglich sind. Und die u.A. pro Zelle(!) die DB um einen Status befragen, der die Farbe beeinflusst. Bitte nicht lachen, mit ist bereits schlecht, ok?

Ein Buffer-Bitmap scheidet hiermit leider aus, weil im Grid auch gescrollt wird.

Die Idee mit ProcessMessages ist gut, das seh ich mir an. Weil ich ProcessMessages um jeden Preis vermeide, habe ich nicht daran gedacht.

Gesteppt habe ich schon, danke für den Tip, sowas mach ich meistens als Erstes.

Die Gesamtheit der Antworten hat mir eine Richtung gezeigt, ich schätze, dass der Datensatzzeiger im Hintergrund auf Unsinn verändert wird und das Grid nochmal zeichnen möchte.

Danke nochmal und lg,
Wolfgang

ConnorMcLeod 4. Apr 2011 13:11

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

in dem Du mal ein Haltpunkt setzt und dann step by step durch gehst und Dir den Code richtig anschaust
Nur als Klarstellung: wenn das WM_PAINT daherkommt und im Haltepunkt hängenbleibt, dann ist es ja schon ausgelöst worden. Nun muss ich draufkommen, warum/wer das ausgelöst hat. Also den *Absender* der Message finden, aber der steht nicht im MessageRecord... :-(

alfold 4. Apr 2011 13:13

AW: Paint Message abfangen/Herkunft finden
 
Vielleicht? hilft hier schon die Komponente/Form DoubleBuffered := True zu setzen?
Das nochmalige zeichen kann zb auch durch ein Changeereignis passieren!
alfold

BUG 4. Apr 2011 13:16

AW: Paint Message abfangen/Herkunft finden
 
Ganz dreckige Idee: Schmeiße die überflüssigen WM_PAINTs einfach weg bzw. spring aus der Behandlungsroutine, wenn du denkst "Nö, jetzt nicht nochmal.".

alfold 4. Apr 2011 13:22

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092901)
Nur als Klarstellung: wenn das WM_PAINT daherkommt und im Haltepunkt hängenbleibt, dann ist es ja schon ausgelöst worden. Nun muss ich draufkommen, warum/wer das ausgelöst hat. Also den *Absender* der Message finden, aber der steht nicht im MessageRecord... :-(

Mir ging es hierbei zu schauen ob evtl Changeereignisse, Vermutung liegt nah, nach seiner letzten Aussage, das doppelzeichen verursachen!

Alla: Create, Paint, Change und darauf wieder Paint!

alfold

blauweiss 4. Apr 2011 14:25

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092898)
Ein Buffer-Bitmap scheidet hiermit leider aus, weil im Grid auch gescrollt wird.

Hallo Wolfgang,

ihr habt doch überhaupt keine andere Wahl, als die Paint-Routine sauber und stabil zu machen.
Sprich unabhängig davon, wann und wie oft WM_PAINT-Messages kommen -> es darf keine Probleme machen und das Ergebnis (Optik und alles was im Hintergrund noch passiert) muß konsistent bleiben.

Diesen Aufwand eines Redesigns müsst ihr m.E. betreiben, alles andere ist Zeitverschwendung.

Gruß,
blauweiss

ConnorMcLeod 4. Apr 2011 14:59

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von alfold (Beitrag 1092906)
Alla: Create, Paint, Change und darauf wieder Paint!

Ahso, verstehe. Hab ich jetzt gecheckt, leider keine neue Erkenntnis, aber Danke für die Idee!
lg Wolfgang

ConnorMcLeod 4. Apr 2011 16:54

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von BUG (Beitrag 1092903)
Ganz dreckige Idee: Schmeiße die überflüssigen WM_PAINTs einfach weg bzw. spring aus der Behandlungsroutine, wenn du denkst "Nö, jetzt nicht nochmal.".

Wenns hart auf hart kommt, mach ich das wirklich, ist ja nur noch für ein paar Monate.
Netter Gedanke, merci!
lg Wolfgang

shmia 4. Apr 2011 16:57

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092847)
Ich habe gefragt, wie schaffe ich *X* und bekomme als Antwort: mach lieber *Y*. Das ist zwar nett gemeint, aber keine wirkliche Hilfe.

Doch, das ist eine echte Hilfe; du sperrst Dich nur dagegen.
Hier im Forum gibt es zusammengenommen hunderte Mannjahre an Erfahrung mit Softwareentwicklung.
Wenn dir also mehrfach ein Rat gegeben wird, denn du eigentlich nicht hören möchtest, dann sollte bei Dir ein Umdenkprozess einsetzen.

Beispiel:
Das Bodenblech deines Autos ist auf der Beifahrerseite stark angerostet und hat Löcher.
Du möchtest Unterbodenschutz draufmachen, weil du im Moment wenig Geld&Zeit hast.
TÜV-Prüfer sagt: "neues Blech einschweisen" und Werkstattmeister sagt das Gleiche und selbst dein Kumpel meint "da muss ein neues Blech rein".
Würdest Du jeweils antworten "das bringt mir aber nichts, ich will nur wissen welchen Unterbodenschutz ist draufmachen soll"??

Teekeks 4. Apr 2011 17:07

AW: Paint Message abfangen/Herkunft finden
 
Zitat:

Zitat von shmia (Beitrag 1092945)
Zitat:

Zitat von ConnorMcLeod (Beitrag 1092847)
Ich habe gefragt, wie schaffe ich *X* und bekomme als Antwort: mach lieber *Y*. Das ist zwar nett gemeint, aber keine wirkliche Hilfe.

Doch, das ist eine echte Hilfe; du sperrst Dich nur dagegen.
Hier im Forum gibt es zusammengenommen hunderte Mannjahre an Erfahrung mit Softwareentwicklung.
Wenn dir also mehrfach ein Rat gegeben wird, denn du eigentlich nicht hören möchtest, dann sollte bei Dir ein Umdenkprozess einsetzen.

Beispiel:
Das Bodenblech deines Autos ist auf der Beifahrerseite stark angerostet und hat Löcher.
Du möchtest Unterbodenschutz draufmachen, weil du im Moment wenig Geld&Zeit hast.
TÜV-Prüfer sagt: "neues Blech einschweisen" und Werkstattmeister sagt das Gleiche und selbst dein Kumpel meint "da muss ein neues Blech rein".
Würdest Du jeweils antworten "das bringt mir aber nichts, ich will nur wissen welchen Unterbodenschutz ist draufmachen soll"??

*Hust*
Er hat doch bereits auf Seite 1 die gründe genannt warum es momentan nicht möglich ist.
Er sucht halt nach einer dreckigen Zwischenlösung bis der Rest auch fertig geschrieben ist.
IMHO ist das OK.

ConnorMcLeod 4. Apr 2011 17:21

AW: Paint Message abfangen/Herkunft finden
 
Sagen wir mal so...

Ich habe eine Rikscha geerbt, auf der ein 3er-Chassis draufsitzt und die Verbindungs-Schrauben werden immer lockerer.
Während ich in der Werkstatt daneben den A6 fertige, muss die Rikscha noch durchhalten und ich schweisse einstweilen ein paar Ersatzschrauben ;-)

Nix gegen Rikschas!

Erstens ist mit Redesign da nichts zu machen. Wegwerfen ist das richtige Wort.
Zweitens ist die Zeit dafür zu schade.

Egal, mit der Datenbank bin ich scheinbar auf dem richtigen Weg. Danke nochmal an alle, ich denke, wir können an dieser Stelle schlussmachen.
Lg Wolfgang


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz