Delphi DefaultHandler(Message)和“消息”之间有什么区别;继承的;在消息处理程序中?

Delphi DefaultHandler(Message)和“消息”之间有什么区别;继承的;在消息处理程序中?,delphi,Delphi,在消息处理程序中调用DefaultHandler(Message)和inherited之间到底有什么区别。e、 g: TScrollBox = class(TScrollingWinControl) private ... procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST; ... end; procedure TScrollBox.WMNCHitTest(var Message: TMessage

在消息处理程序中调用
DefaultHandler(Message)
inherited
之间到底有什么区别。e、 g:

TScrollBox = class(TScrollingWinControl)
private
  ...
  procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST;
  ...
end;

procedure TScrollBox.WMNCHitTest(var Message: TMessage);
begin
  DefaultHandler(Message);
end;

为什么不在这里调用继承的?什么时候我应该使用?

让我们考虑一下你提供的例子。假设没有调用
DefaultHandler
,而是调用了inherited(或者等价地,TScrollBox没有实现任何
WM\u nchitest
消息处理程序)。在这种情况下,消息将由
TWinControl
通过以下方法处理:

procedure TWinControl.WMNCHitTest(var Message: TWMNCHitTest);
begin
  with Message do
    if (csDesigning in ComponentState) and (FParent <> nil) then
      Result := HTCLIENT
    else
      inherited;
end;
它直接调用
DefaultHandler
,因此无条件地将消息转发到默认窗口过程

因此,我们由此得出的结论是,
TScrollBox.WMNCHitTest
通过抑制返回
HTCLIENT
TWinControl.WMNCHitTest
中的代码,简单地改变了设计时的行为


因此,我推测这就是这个VCL代码的作者的动机。通过使用
DefaultHandler
恢复基础窗口的行为(由默认窗口过程确定),删除由介入VCL代码执行的任何行为修改。

在特定情况下很难确定。DefaultHandler(理论上)处理消息处理程序仅处理一条消息的所有消息。默认处理程序是公共虚拟方法,因此可以显式重写。消息处理程序不是声明为虚拟的,并且通常是私有的,因此,例如,如果替换

inherited;

编译将失败

另一个问题是哪个祖先优先于什么。因此,一个祖先可能会覆盖消息处理程序,而另一个祖先可能会覆盖默认处理程序,这使得在没有大量挖掘的情况下非常混乱

所以我想对我来说,我必须依靠似乎最适合文档的东西。这意味着,在一般情况下,我会使用继承,因为我依赖于这个特定消息的祖先实现,而不是一般消息的祖先实现


我想这是另一种说法-我会采用Victoria的方法。

如果您正在编写消息处理程序,请决定如何处理该消息(例如,此消息是一个很好的示例,您应该清楚地定义消息结果,而不是依赖
DefaultHandler
提供的内容)。我不是试图做出判断,我只是解释问题中的代码的作用。小报复投票并不漂亮。@Victoria,
此消息是一个很好的例子,您应该清楚地定义消息结果,而不是依赖DefaultHandler提供的内容
,那么您建议如何处理此消息?@DavidHeffernan,如果该消息处理程序为空,会发生什么?在这种情况下不应该有一个默认的处理程序吗?前者是一个错误,因为窗口过程被收缩以返回一个值。后者是返回
HTCLIENT
的一种误导方式,因为
HTCLIENT
具有值
1
。行为上存在明显差异。如果在
TScrollBox.WMNCHitTest
中,对
DefaultHandler
的调用被替换为
继承的
,则设计时行为将被更改。是的,对于一种很少使用的运行时重写。如果我要处理某些信息,我知道怎么做。如果我的控件将有需要在设计时响应的滚动条,我会在该消息中这样说。我不确定我是否明白您关于
的观点消息处理程序不是声明为虚拟的,而且通常是私有的
。调用继承的
将继承祖先消息处理程序。@zig是的,它将调用祖先消息处理程序。但这不是正常的继承形式,这就是我要说的。通常不能从私有方法继承。如果消息方法与消息匹配,则会覆盖它们(无论使用什么方法名称)。调用
inherited
开始调用类层次结构中的所有实现(调用
inherited
),直到它到达
TObject.DefaultHandler
。如果调用
DefaultHandler
,将调用所有
DefaultHandler
重写(只要调用
inherited
方法),直到
TObject.DefaultHandler
。无论如何,您必须知道它们实现了什么。
inherited;
inherited WMNCHitTest( message );