TEdit und WM_PAINT Message-Handler seltsames Verhalten

8

Ich versuche, meine eigene Zeichnung in einem TEdit -Steuerelement zu implementieren, wenn sie keinen Fokus hat (zeige Ellipsen in TEdit , wenn der Editor seinen Text nicht vollständig anzeigt). Also habe ich mit diesem Code angefangen:

%Vor%

Beachten Sie, dass der Nachrichtenhandler bei FEllipsis and (not Focused) nichts tut.

Jetzt habe ich die Steuerelemente TButton und 2 TEdit im Formular gelöscht und das Formular OnCreate hinzugefügt:

%Vor%

Ich habe erwartet, dass Edit1 normal zeichnet, und Edit2 , um nichts in das Bearbeitungssteuerelement zu zeichnen.

Stattdessen wurde der Message-Handler endlos verarbeitet, Edit1 wurde auch nicht gezeichnet, und die gesamte Anwendung war erstickt (mit 25% CPU-Auslastung!). Ich habe auch versucht, Message.Result := 0 - selbe Wirkung zurückzugeben.

Nun zum "seltsamen" Teil: Wenn ich das Canvas-Handle mit BeginPaint erhalte, funktioniert alles wie erwartet.

%Vor%

Beachten Sie, dass ich auch inherited nicht aufgerufen habe.

Wie erklärt man dieses Verhalten? Danke.

    
zig 31.10.2017, 12:10
quelle

1 Antwort

13

Wenn ein Fenster ungültig wird, wird es aufgefordert, sich beim nächsten Malzyklus gültig zu machen. In der Regel geschieht dies in der Hauptthread-Nachrichtenschleife, wenn GetMessage feststellt, dass die Warteschlange leer ist. An diesem Punkt werden WM_PAINT -Nachrichten synthetisiert und an das Fenster gesendet.

Wenn das Fenster diese Nachrichten empfängt, muss es sich selbst malen. Dies geschieht normalerweise mit Aufrufen von BeginPaint und dann EndPaint . Der Aufruf von BeginPaint validiert das Client-Rect des Fensters. Dies ist die kritische Information, die Ihnen fehlt.

Nun haben Sie in Ihrem Code inherited nicht aufgerufen und so nichts gezeichnet und BeginPaint / EndPaint nicht aufgerufen. Da Sie BeginPaint nicht aufgerufen haben, bleibt das Fenster ungültig. Und so wird ein endloser Stream von WM_PAINT -Nachrichten generiert.

Die entsprechende Dokumentation finden Sie hier :

  

Die Funktion BeginPaint validiert automatisch den gesamten Client-Bereich.

    
David Heffernan 31.10.2017, 12:22
quelle

Tags und Links