[英]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
事件如此多次?
Create a new VCL Forms Application with two TButton
controls, one TMemo
control, and one TBitBtn
control. 使用两个
TButton
控件,一个TMemo
控件和一个TBitBtn
控件创建一个新的VCL Forms应用程序。
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
. 将鼠标移到
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.