在Delphi中,如何在基类及其后代类中启用方法指针属性

问题描述 投票:2回答:1

我想创建一个TService后代类,该类用作Windows服务实现的基础。在我的基类中,我引入一个已发布的ServiceDescription属性,并使用AfterInstall事件处理程序将此描述写到Windows注册表中的适当位置。

[请注意,由于TServer类(在Vcl.SvcMgr中声明)是TDataModule后代,因此为了使ServiceDescription属性在对象检查器中可见,必须在设计时包,并使用对RegisterCustomModule的调用在Delphi中进行注册。此外,此基类的后代必须由OTA(开放工具api)向导或某种类型的代码生成器(.pas和.dfm文件)生成。没问题,我已经整理了其中的一种,如果您有兴趣,可以从Marco Cantu的书(http://www.marcocantu.com/ddh/ddh15/ddh15e.htm)中阅读有关它的更多信息。

我遇到的麻烦是,我想在基类中使用AfterInstall事件处理程序写入注册表,并在AfterUninstall中删除它,但是我想确保我的后代类也将支持AfterInstallAfterUninstall事件。

我以前从Ray Konopka那里了解到,如果要重新引入一个属性,则必须在后代类中使用访问器方法。结果,这是一个代码段,代表我针对AfterInstall事件执行此操作的尝试:

  private
    // field to store method pointer for the descendant AfterInstall event handler
    FFAfterInstall: TServiceEvent;
    …
  protected
    function GetAfterInstall: TServiceEvent;
    procedure SetAfterInstall( value: TServiceEvent );
    …
  published
    property AfterInstall: TServiceEvent read GetAfterInstall write SetAfterInstall;

我重写的构造函数将方法分配给继承的AfterInstall属性:

constructor TTPMBaseService.Create(AOwner: TComponent);
begin
  inherited;
  // Hook-up the AfterInstall event handlers
  Self.AfterInstall := CallAfterInstall;
  …
end;

[在CallAfterInstall的实现中,运行代码写入Windows注册表后,我测试是否将方法指针分配给了本地方法指针字段,如果是,则调用它。看起来像这样:

procedure TTPMBaseService.CallAfterInstall(Service: TService);
var
  Reg: TRegistry;
begin
  // Code here to write to the Windows Registry is omitted
  // Test if our method pointer field has been written to
  if Assigned( FFAfterInstall ) then
    FFAfterInstall( Service );  // call the method,
  …
end;

我认为这一切都非常有意义,我认为这应该可行。但是,我仍然坚持使用accessor方法。 Get访问器方法可以正常编译,在这里是:

function TTPMBaseService.GetAfterInstall: TServiceEvent;
begin
  Result := FFAfterInstall;
end;

但是我的SetAfterInstall方法引发了一个编译时异常,报告没有足够的参数:

procedure TTPMBaseService.SetAfterInstall( value: TServiceEvent );
begin
  if value <> FFAfterInstall then
    FFAfterInstall := value;
end;

我不确定在这里做什么。我进行了以下更改,并进行了编译,但似乎没有完成该工作:

procedure TTPMBaseService.SetAfterInstall( value: TServiceEvent);
begin
  if @value <> @FFAfterInstall then
    @FFAfterInstall := @value;
end;

我有两个问题。首先是,在确保我的基类及其后代都支持此事件的同时,我是否采用正确的方法重新引入了事件处理程序?如果我的逻辑正确,那么Setter访问器方法在做什么?

我想创建一个TService后代类,将其用作Windows服务实现的基础。在我的基类中,我将介绍一个已发布的ServiceDescription属性,并使用...

oop delphi windows-services
1个回答
2
投票

我采用正确的方法重新引入事件处理程序吗?

© www.soinside.com 2019 - 2024. All rights reserved.