为什么当鼠标移到 TButton 上时会多次触发 Form Paint 事件

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

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

  1. 使用两个 TButton 控件、一个 TMemo 控件和一个 TBitBtn 控件创建一个新的 VCL Forms 应用程序。

  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次。

当 "Project/Options/Application/Appearance" 中的样式更改为例如"Luna",我会得到这个行为:

当鼠标移到TButton/TBitBtn上时,OnPaint事件触发1次,鼠标移出[=12]事件时触发2次=]/TBitBtn.

为什么不一致?

当鼠标移到 TButton 上时是否可以避免 OnPaint 事件?

我有 XE8 订阅更新 1(和 Windows 10)。

按钮的悬停效果决定了您观察到的内容。当您将鼠标悬停在按钮上时,它会改变外观。当您将光标从按钮上移开时,它会恢复其外观。每次外观更改都会触发表单的 OnPaint 事件。这就是底层绘画系统的工作原理。为了绘制子控件,WM_PRINTCLIENT 消息被传送到控件的父控件,这反过来导致窗体的 OnPaint 事件触发。

您可以通过禁用运行时主题看到这种情况。当您这样做时,将光标移动到按钮上不会导致 OnPaint 被触发。

VCL 样式和 Windows 主题导致触发不同数量的 OnPaint 事件的原因很简单,就是它们以不同的方式处理绘画。但是 VCL 样式也有悬停效果,它们也会导致 OnPaint 事件被触发。

Is it possible to avoid the OnPaint event when the cursor is moved over a button?

在 VCL 风格的应用程序中,您可能会使用没有任何悬停效果的 VCL 风格。在 Windows 主题应用中,您可以禁用按钮的主题。

我怀疑解决您真正问题的方法,即您未提出的问题的答案,是停止使用 OnPaint,无论您目前使用它做什么。而是在更合适的地方做任何你在那里做的事。