为什么当鼠标移过TButton时,FormPaint事件会触发多次

时间:2015-09-16 07:17:55

标签: delphi windows-10 delphi-xe8

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

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

  2. 使用此代码:

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

  4. 当鼠标移动到TButton时,OnPaint事件会被触发4次,当鼠标从TButton移出时会被触发4次。

    当鼠标移动到TBitBtn时,OnPaint事件会被触发3次,当鼠标从TBitBtn移出时会触发3次。

    在“项目/选项/应用程序/外观”中将样式更改为例如“Luna”,我会改变这种行为:

    当鼠标移动到TButton / TBitBtn时,OnPaint事件会被触发1次,当鼠标从TButton移出时会被触发2次/ TBitBtn

    为什么不一致?

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

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

1 个答案:

答案 0 :(得分:3)

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

您可以通过禁用运行时主题来了解这种情况。执行此操作时,将光标移到按钮上不会导致OnPaint被触发。

VCL样式和Windows主题导致不同数量的OnPaint事件被触发的原因只是他们以不同的方式处理绘画。但VCL样式也会悬停在效果上,并且还会导致OnPaint事件被触发。

  

当光标移到按钮上时,是否可以避免OnPaint事件?

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

我怀疑您真正问题的解决方案,即您未提出问题的答案,就是暂停使用OnPaint来处理您目前使用它的任何内容。而是在更合适的地方做任何你做的事。