Thomas
Thomas

Reputation: 375

Why is the FormPaint event triggered mutilple times when mouse is moved over a TButton

Why is the Form's OnPaint event triggered so many times in this application?

  1. Create a new VCL Forms Application with two TButton controls, one TMemo control, and one TBitBtn control.

  2. Use this code:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Clear;
    end;
    
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      Memo1.Lines.Add('FormPaint');
    end;
    
  3. 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

Answers (1)

David Heffernan
David Heffernan

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

Related Questions