Ich versuche, meine eigene Zeichnung auf einem Steuerelement zu implementieren, wenn es keinen Fokus hat (Ellipsen in TEdit
anzeigen, wenn der Editor seinen Text nicht vollständig anzeigt). So Star I א ed mit diesem Code:TEdit und WM_PAINT Message-Handler merkwürdiges Verhalten
type
TEdit = class(StdCtrls.TEdit)
private
FEllipsis: Boolean;
FCanvas: TCanvas;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEllipsis := False;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
end;
destructor TEdit.Destroy;
begin
FCanvas.Free;
inherited;
end;
procedure TEdit.WMPaint(var Message: TWMPaint);
begin
if FEllipsis and (not Focused) then
begin
// Message.Result := 0;
// TODO...
end
else
inherited;
end;
Beachten Sie, dass, wenn FEllipsis and (not Focused)
der Nachrichten-Handler nichts tut.
Nun fiel mir ein TButton
und 2 TEdit
Steuerelemente auf dem Formular, und hinzugefügt Form OnCreate
:
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit2.FEllipsis := True;
end;
ich Edit1
normalerweise zu ziehen erwartet und Edit2
nichts in dem Edit-Control zu ziehen.
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
zurückzukehren - gleicher Effekt.
Jetzt für den "seltsamen" Teil: Wenn ich das Canvas-Handle mit BeginPaint
bekomme, funktioniert alles wie erwartet.
procedure TEdit.WMPaint(var Message: TWMPaint);
var
PS: TPaintStruct;
begin
if FEllipsis and (not Focused) then
begin
if Message.DC = 0 then
FCanvas.Handle := BeginPaint(Handle, PS)
else
FCanvas.Handle := Message.DC;
try
// paint on FCanvas...
finally
FCanvas.Handle := 0;
if Message.DC = 0 then EndPaint(Handle, PS);
end;
end
else
inherited;
end;
Beachten Sie, dass ich nicht inherited
entweder aufgerufen habe.
Wie wird dieses Verhalten erläutert? Vielen Dank.
Vielen Dank! Die Dokumentation machte es klar: * "Das System generiert weiterhin WM_PAINT-Nachrichten, bis der aktuelle Aktualisierungsbereich validiert ist" * – zig
Dies muss die beste kurze Beschreibung des Windows-Nachricht-Malprozesses sein, den ich bisher gelesen habe. –