Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Delphi中的消息处理程序方法忽略了它是;“私人”;_Oop_Delphi_Windows Messages - Fatal编程技术网

Oop Delphi中的消息处理程序方法忽略了它是;“私人”;

Oop Delphi中的消息处理程序方法忽略了它是;“私人”;,oop,delphi,windows-messages,Oop,Delphi,Windows Messages,有两个类:TBaseClass和TDerivedClass,都是以单独的单元表示的 TBaseClass unit InhPriv.BaseClass; interface uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages; type TBaseClass = class(TWinControl) strict private procedure TheMethod(var msg: T

有两个类:
TBaseClass
TDerivedClass
,都是以单独的单元表示的

TBaseClass

unit InhPriv.BaseClass;

interface

uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages;

type
  TBaseClass = class(TWinControl)
  strict private
    procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
  end;

implementation

procedure TBaseClass.TheMethod(var msg: TMessage);
begin
  MessageBox(0, 'TBaseClass.TheMethod', 'IhheritedPrivateTest', 0);
end;

end.
unit InhPriv.DerivedClass;

interface

uses InhPriv.BaseClass, Winapi.Windows, Winapi.Messages, InhPriv.Messages;

type
  TDerivedClass = class(TBaseClass)
  public
    procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
  end;

implementation

procedure TDerivedClass.TheMethod(var msg: TMessage);
begin
  inherited; //TBaseClass.TheMethod gets called!!!
  MessageBox(0, 'TDerivedClass.TheMethod', 'IhheritedPrivateTest', 0);
end;

end.
tDelivedClass

unit InhPriv.BaseClass;

interface

uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages;

type
  TBaseClass = class(TWinControl)
  strict private
    procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
  end;

implementation

procedure TBaseClass.TheMethod(var msg: TMessage);
begin
  MessageBox(0, 'TBaseClass.TheMethod', 'IhheritedPrivateTest', 0);
end;

end.
unit InhPriv.DerivedClass;

interface

uses InhPriv.BaseClass, Winapi.Windows, Winapi.Messages, InhPriv.Messages;

type
  TDerivedClass = class(TBaseClass)
  public
    procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
  end;

implementation

procedure TDerivedClass.TheMethod(var msg: TMessage);
begin
  inherited; //TBaseClass.TheMethod gets called!!!
  MessageBox(0, 'TDerivedClass.TheMethod', 'IhheritedPrivateTest', 0);
end;

end.
主机表单

TForm1 = class(TForm)
//.......
private
  c: TDerivedClass;
//.......
end;
WM\u CUSTOM
定义为
WM\u用户+1

调用方法

变体1:发送消息:

输出:

t基本类。方法
tDelivedClass.TheMethod

变量2:直接调用方法:

输出:

t基本类。方法
tDelivedClass.TheMethod

CPU窗口

这是一个直接的方法调用

InhPriv.DerivedClass.pas.17: inherited; //TBaseClass.TheMethod gets called!!!
005B4880 8B55F8           mov edx,[ebp-$08]
005B4883 8B45FC           mov eax,[ebp-$04]
005B4886 E87DFDFFFF       call TBaseClass.TheMethod
Delphi文档说明:

当继承的之后没有标识符时,它引用与封闭方法同名的继承方法,或者,如果封闭方法是消息处理程序,则引用同一消息的继承消息处理程序

所以,并没有明确的词语表明将方法转换为消息处理程序会使Delphi编译器违反OOP原则


我可能错过了一些文档吗?

考虑到消息处理程序是可以“调用”的,即使来自不同的进程,我不确定您在那里期望的是什么。在基类中限定私有方法的范围可以确保在子类中看不到它(除非两者在同一个单元中)。但是在您的描述中,您重新定义了
方法的范围,因此您可以在那里调用它。我想这是个小骗局。
method
private
作用域仅用于隐藏该方法,而不是使
继承的
不起作用。如果我错了,请纠正我,因为这只是猜测导致此行为的原因。消息调度不关心方法可见性。如果
tDelivedClass.TheMethod()
试图显式调用
TBaseClass.TheMethod()
,由于可见性问题,该方法将无法工作。但是
inherited
并不关心这一点。当我测试这一点(在Delphi XE2中)时,似乎有没有消息指令并不重要,但是调用简单的inherited而没有方法名这一事实才是重要的。这似乎绕过了严格的私人警卫。这是功能还是bug?