Override SetEnabled vs. handling message CM_ENABLEDCHANGED

delphi, delphi-10.1-berlin, message-queue, overriding

Solution

Handling `CM_ENABLEDCHANGED` is the correct solution. Such `CM_...` messages are specifically designed to allow descendant classes to react to changes to properties that are declared in base classes.

For example:

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;

Alternatively:

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;

Problem

There is a `TFrame` descendant class as follows: ``` TCustomHistoryFrame = class(TFrame) tbMainFunction: TToolBar; // there's more, of course, but that is irrelevant to the question end; ``` I noticed, that when I set `Enabled` property of this frame to `False`, its component `tbMainFunction` won't get (visually) disabled. My first idea was to override virtual method `TControl.SetEnabled`. Looking at its implementation, I saw that it performs control message `CM_ENABLEDCHANGED` when the value of actually differs. I am not sure on how to apply the frame's `Enabled` state to the toolbar the right way. What would be the common way to do? As this question would be primarily opinion based, let me rephrase it: What advantages and disadvantages are there for either overriding `SetEnabled` or handling `CM_ENABLEDCHANGED`? Things, I thought of myself: - override `SetEnabled`: - I would have to recheck, whether the new value differs from the old value. That would be a redundancy. (Which would have no significant influence on performance, but - call me a hair-splitter - smells to me.) - handling `CM_ENABLEDCHANGED`: - How do I sustain inherited code for this message? There are implementations for this message (at least) in `TControl` and `TWinControl`. Would they still be executed, if I handle the message in my class `TCustomHistoryFrame`?

Original source