覆盖SetEnabled与处理消息CM_ENABLEDCHANGED

Ren*_*ann 3 delphi overriding 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

无论是重写SetEnabled还是处理都有哪些优点和缺点CM_ENABLEDCHANGED


事情,我想到了自己:

  • 覆盖SetEnabled:
    • 我必须重新检查新值是否与旧值不同.这将是一种冗余.(这对性能没有显着影响,但是 - 叫我一个头发分裂器 - 闻我.)
  • 处理CM_ENABLEDCHANGED:
    • 如何维护此消息的继承代码?在(TControl和)中有(至少)此消息的实现TWinControl.如果我在课堂上处理这些信息,他们还会被执行TCustomHistoryFrame吗?

Rem*_*eau 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;
Run Code Online (Sandbox Code Playgroud)

或者:

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;
Run Code Online (Sandbox Code Playgroud)