为什么当鼠标移动到TButton上时,会触发多次FormPaint事件?



为什么表单的OnPaint事件在这个应用程序中被触发了这么多次?

  1. 创建一个新的VCL表单应用程序,包含两个TButton控件,一个TMemo控件和一个TBitBtn控件。

  2. 使用以下代码:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Clear;
    end;
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      Memo1.Lines.Add('FormPaint');
    end;
    
  3. 运行应用程序。

当鼠标移动到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为任何你正在使用它目前。在更合适的地方做你该做的事。

最新更新