覆盖 SetEnabled 与处理消息 CM_ENABLEDCHANGED
Override SetEnabled vs. handling message CM_ENABLEDCHANGED
有TFrame
个后代class如下:
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
:
- 如何维持此消息的继承代码?在
TControl
和 TWinControl
中(至少)有此消息的实现。如果我在 class TCustomHistoryFrame
中处理消息,它们还会被执行吗?
处理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;
有TFrame
个后代class如下:
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
:- 如何维持此消息的继承代码?在
TControl
和TWinControl
中(至少)有此消息的实现。如果我在 classTCustomHistoryFrame
中处理消息,它们还会被执行吗?
- 如何维持此消息的继承代码?在
处理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;