我想创建一个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
中删除它,但是我想确保我的后代类也将支持AfterInstall
和AfterUninstall
事件。
我以前从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属性,并使用...
我采用正确的方法重新引入事件处理程序吗?