当消息处理程序不调用inherited时会发生什么?

时间:2017-08-28 12:27:47

标签: delphi

我刚才注意到我们的一个非常(非常)旧的自定义控件(不是我创建的)有这个WM_SIZE消息处理程序(我在这里使用TPanel进行演示):

TPanel = class(ExtCtrls.TPanel)
private
  procedure WMSize(var Message: TWMSize); message WM_SIZE;
end;

procedure TPanel.WMSize(var Message: TWMSize);
begin
  DoSomethingWhenResized;
end;

未调用inheritedDoSomethingWhenResized创建一个缓存的渐变位图,用于控件的绘制过程。

每件事“看起来”并且表现得很好,但我只是怀疑不是首先调用inherited处理程序是否会出错?

1 个答案:

答案 0 :(得分:8)

当然,如果你不调用inherited,那么你将失去在祖先控件中实现的行为。这是否是一个问题只有你可以决定。 VCL源显示了这些祖先正在做的事情。在您的示例中,处理WM_SIZE的链的第一个祖先是TWinControl,它执行此操作:

procedure TWinControl.WMSize(var Message: TWMSize);
var
  LList: TList;
begin
  UpdateBounds;
  UpdateExplicitBounds;
  inherited;

  LList := nil;
  if (Parent <> nil) and (Parent.FAlignControlList <> nil) then
    LList := Parent.FAlignControlList
  else if FAlignControlList <> nil then
    LList := FAlignControlList;

  if LList <> nil then
  begin
    if LList.IndexOf(Self) = -1 then
      LList.Add(Self);
  end
  else
  begin
    Realign;
    if not (csLoading in ComponentState) then
      Resize;
  end;
end;

此处WMSize调用了inherited,但是(目前)TWinControl以上没有实现此目的的祖先对象,所以上面就是你没有调用{{1} }。如果您的inherited管理您的控件边界,大小调整和子控件的组件对齐(或者如果您不需要它来执行此操作)那么您就可以了。但是,如果您发现控件未正确处理这些内容,那么您可能会怀疑DoSomethingWhenResized在实现过程中遗漏了一项或多项责任。