覆盖SetEnabled与处理消息CM_ENABLEDCHANGED

时间:2017-05-09 06:56:13

标签: delphi override message-queue delphi-10.1-berlin

有一个TFrame后代类如下:

TCustomHistoryFrame = class(TFrame)
  tbMainFunction: TToolBar;
  // there's more, of course, but that is irrelevant to the question
end;

我注意到,当我将此框架的Enabled属性设置为False时,其组件tbMainFunction将无法(视觉上)禁用。

我的第一个想法是覆盖虚方法TControl.SetEnabled。看看它的实现,我发现当实际值不同时它会执行控制消息CM_ENABLEDCHANGED

我不确定如何以正确的方式将框架的Enabled状态应用到工具栏 常见的做法是什么?由于这个问题主要是以观点为基础的,所以让我重新说一下:

覆盖SetEnabled或处理CM_ENABLEDCHANGED有哪些优缺点?

事情,我想到了自己:

  • 覆盖SetEnabled
    • 我必须重新检查新值是否与旧值不同。这将是一种冗余。 (这对性能没有显着影响,但是 - 叫我一个分发器 - 闻我的味道。)
  • 处理CM_ENABLEDCHANGED
    • 如何维护此邮件的继承代码? TControlTWinControl中有此消息的实现(至少)。如果我在班级TCustomHistoryFrame处理邮件,它们仍会被执行吗?

1 个答案:

答案 0 :(得分:5)

处理CM_ENABLEDCHANGED是正确的解决方案。此类CM_...消息专门用于允许后代类对基类中声明的属性的更改做出反应。

例如:

TCustomHistoryFrame = class(TFrame)
  tbMainFunction: TToolBar;
private
  procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
end;

procedure TCustomHistoryFrame.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  tbMainFunction.Enabled := Enabled;
end;

可替换地:

TCustomHistoryFrame = class(TFrame)
  tbMainFunction: TToolBar;
protected
  procedure WndProc(var Message: TMessage); override;
end;

procedure TCustomHistoryFrame.WndProc(var Message: TMessage);
begin
  inherited;
  if Message.Msg = CM_ENABLEDCHANGED then
    tbMainFunction.Enabled := Enabled;
end;