为什么表单的OnPaint
事件在这个应用程序中被触发了这么多次?
-
创建一个新的VCL表单应用程序,包含两个
TButton
控件,一个TMemo
控件和一个TBitBtn
控件。 -
使用以下代码:
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.Clear; end; procedure TForm1.FormPaint(Sender: TObject); begin Memo1.Lines.Add('FormPaint'); end;
-
运行应用程序。
当鼠标移动到TButton
上时,OnPaint
事件触发4次,当鼠标移动到TButton
外时触发4次。
当鼠标移动到TBitBtn
上时,OnPaint
事件触发3次,当鼠标移动到TBitBtn
上时触发3次。
当"项目/选项/应用程序/外观"中的样式更改为例如:"Luna",我将得到这样的行为:
当鼠标移动到TButton
/TBitBtn
上时,OnPaint
事件触发1次,当鼠标移动到TButton
/TBitBtn
上时触发2次。
为什么不一致?
当鼠标移动到TButton
上时,是否有可能避免OnPaint
事件?
我有XE8订阅更新1(和Windows 10)。
按钮的悬停效果负责您观察到的内容。当您将鼠标悬停在按钮上时,它会改变外观。当您将光标从按钮上移开时,它将恢复其外观。每次更改外观都会触发表单的OnPaint
事件。这就是底层绘画系统的工作原理。为了绘制子控件,将WM_PRINTCLIENT
消息传递给控件的父控件,然后触发窗体的OnPaint
事件。
您可以通过禁用运行时主题看到这种情况。当您这样做时,将光标移动到按钮上不会导致OnPaint
被触发。
VCL样式和Windows主题导致不同数量的OnPaint
事件被触发的原因很简单,它们以不同的方式处理绘画。但是VCL样式也有悬停效果,它们也会导致OnPaint
事件被触发。
当光标移动到按钮上时,是否有可能避免
OnPaint
事件?
在一个VCL样式的应用程序中,你可能会使用一个没有任何悬停效果的VCL样式。在Windows主题的应用程序中,你可以禁用按钮的主题。
我怀疑你真正问题的解决方案,你没有问过的问题的答案,是停止使用OnPaint
为任何你正在使用它目前。在更合适的地方做你该做的事。