简体   繁体   English

为什么将鼠标移到TButton上时,FormPaint事件被触发了多次?

[英]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? 为什么在此应用程序中触发了窗体的OnPaint事件如此多次?

  1. Create a new VCL Forms Application with two TButton controls, one TMemo control, and one TBitBtn control. 使用两个TButton控件,一个TMemo控件和一个TBitBtn控件创建一个新的VCL Forms应用程序。

  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 . 将鼠标移到TButton ,将触发OnPaint事件4次,将鼠标从TButton移出时将触发4次。

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 . 将鼠标移到TBitBtn ,将触发OnPaint事件3次,将鼠标从TBitBtn移出时将触发3次。

When the style is changed in "Project/Options/Application/Appearance" to eg "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 . 将鼠标移到TButton / TBitBtn ,将触发OnPaint事件1次,将鼠标从TButton / TBitBtn移出2次。

Why the inconsistency? 为什么不一致?

Is it possible to avoid the OnPaint event when the mouse is moved over a TButton ? 将鼠标移到TButton时,是否可以避免OnPaint事件?

I have XE8 Subscription Update 1 (and Windows 10). 我有XE8订阅更新1(和Windows 10)。

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. 外观的每次更改都会导致触发表单的OnPaint事件。 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. 为了绘制子控件,将WM_PRINTCLIENT消息传递到控件的父控件,该消息进而导致表单的OnPaint事件触发。

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. 当您这样做时,将光标移到按钮上不会导致触发OnPaint

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. VCL样式和Windows主题导致触发不同数量的OnPaint事件的原因仅仅是因为它们以不同的方式处理绘画。 But VCL styles also has hover over effects, and they also lead to OnPaint events being fired. 但是,VCL样式也具有悬停效果,它们还会导致触发OnPaint事件。

Is it possible to avoid the OnPaint event when the cursor is moved over a button? 当光标移到按钮上方时,是否可以避免OnPaint事件?

In a VCL styled app you could probably use a VCL style that did not have any hover effects. 在VCL样式的应用程序中,您可能会使用没有任何悬停效果的VCL样式。 In a Windows themed app you could disable the theme for the button. 在Windows主题的应用程序中,您可以禁用按钮的主题。

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. 我怀疑您真正的问题的解决方案(未解决的问题的答案)是停止使用OnPaint来处理目前使用的任何内容。 Instead do whatever you do there in a more appropriate place. 相反,您可以在更合适的地方进行任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM