Reputation: 375
Why is the Form's OnPaint
event triggered so many times in this application?
Create a new VCL Forms Application with two TButton
controls, one TMemo
control, and one TBitBtn
control.
Use this code:
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Clear;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
Memo1.Lines.Add('FormPaint');
end;
Run the application.
When the mouse is moved onto a TButton
, the OnPaint
event is triggered 4 times, and 4 times when the mouse is moved out from the TButton
.
When the mouse is moved onto a TBitBtn
, the OnPaint
event is triggered 3 times, and 3 times when the mouse is moved out from the TBitBtn
.
When the style is changed in "Project/Options/Application/Appearance" to e.g. "Luna", I will get this behavior instead:
When the mouse is moved onto a TButton
/TBitBtn
, the OnPaint
event is triggered 1 time, and 2 times when the mouse is moved out from the TButton
/TBitBtn
.
Why the inconsistency?
Is it possible to avoid the OnPaint
event when the mouse is moved over a TButton
?
I have XE8 Subscription Update 1 (and Windows 10).
Upvotes: 0
Views: 368
Reputation: 613382
The hover over effect of the buttons is responsible for what you observe. When you hover over a button, it changes appearance. When you move the cursor away from the button, it reverts its appearance. Each change of appearance leads to the form's OnPaint
event being fired. That is just how the underlying painting system works. In order to paint the child control, a WM_PRINTCLIENT
message is delivered to the control's parent, and that in turn leads to the form's OnPaint
event firing.
You can see that this is the case by disabling runtime themes. When you do that, moving the cursor over the buttons does not cause OnPaint
to be fired.
The reason that VCL styles and Windows themes lead to different numbers of OnPaint
events being fired is simply that they handle the painting in different ways. But VCL styles also has hover over effects, and they also lead to OnPaint
events being fired.
Is it possible to avoid the
OnPaint
event when the cursor is moved over a button?
In a VCL styled app you could probably use a VCL style that did not have any hover effects. In a Windows themed app you could disable the theme for the button.
I suspect that the solution to your real problem, the answer to your un-asked question, is to stop using OnPaint
for whatever you are using it for at present. Instead do whatever you do there in a more appropriate place.
Upvotes: 3