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

7

我刚刚注意到我们非常(非常)古老的自定义控件(不是由我创建的)有这个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;

inherited 没有被调用。 DoSomethingWhenResized 创建了一个缓存的渐变位图,该位图在控件的绘制过程中使用。

一切“看起来”和运行正常,但我想知道如果首先调用 inherited 处理程序,是否会出现任何问题?


取决于情况。唯一发生的事情是祖先消息处理程序的代码不会被调用。如果您自己处理消息,则无需调用 inherited - Victoria
1个回答

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之上实现了它,所以没有调用inherited就会缺少这个。如果你的DoSomethingWhenResized管理了你的控件边界、大小和子控件的组件对齐(或者你不需要它这样做),那么你就没问题了。但是,如果你发现控件不能正确地处理这些事情,那么你可能会怀疑DoSomethingWhenResized在其实现中漏掉了其中一个或多个责任。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接