我想在构造函数中分配一个事件处理程序,如果它没有分配.因此,我想删除析构函数中最终分配的事件处理程序.我编写的代码如下,但无法编译.
constructor TSomeControl.Create(Panel: TPanel);
begin
inherited Create;
FPanel := Panel;
if not Assigned(FPanel.OnResize) then
FPanel.OnResize := HandlePanelResize;
end;
destructor TSomeControl.Destroy;
begin
if @FPanel.OnResize = @HandlePanelResize then // [dcc32 Error] E2036 Variable required
FPanel.OnResize := nil;
FPanel := nil;
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
如何正确测试?我知道解决方案是使用变量来记录,无论我是否已分配OnResize.但我不希望这作为解决方案.
我想创建一个TService后代类,用作我的 Windows 服务实现的基础。在我的基类中,我引入了一个已发布的ServiceDescription属性,并且我正在使用AfterInstall事件处理程序将此描述写入 Windows 注册表中的适当位置。
请注意,由于TServer类(在 中声明Vcl.SvcMgr)是TDataModule后代,为了允许ServiceDescription属性在对象检查器中可见,有必要在设计时包中声明此基类,并使用对 的调用在 Delphi 中注册它RegisterCustomModule。此外,此基类的后代必须由 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 …Run Code Online (Sandbox Code Playgroud) 我正在尝试检查是否TNotifyEvent已经为某个特定事件分配了一个事件()procedure(Sender: TObject) of object.
这是我的示例代码:
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if(Button1.OnClick = Button1Click) then
begin
//...
end;
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我收到以下错误消息:
[DCC错误] Unit1.pas(28):E2035实际参数不足
所以,我尝试过如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
if(@Button1.OnClick = @Button1Click) then
begin
//...
end;
end;
Run Code Online (Sandbox Code Playgroud)
在编译时,错误更改为:
[DCC错误] Unit1.pas(28):E2036需要变量
我如何检查是否Button1.OnClick指向Button1Click?
我似乎处于 catch 22 的情况。我想添加编译器版本相关代码。好的 - 这是非常标准的。但是 $IF 语句的语法因版本而异。
这是我想要实现的目标
{$IF CompilerVersion = 28}
if (fPendingObject = pObject) and (Addr(fPendingActionEvent) = Addr(pPendingActionEvent) ) then
{$ELSE}
if (fPendingObject = pObject) and (@fPendingActionEvent = @pPendingActionEvent ) then
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
这在 Delphi XE7 中编译,但不在西雅图或柏林编译。这些编译器需要语法
{$IF CompilerVersion = 28}
if (fPendingObject = pObject) and (Addr(fPendingActionEvent) = Addr(pPendingActionEvent) ) then
{$ELSE}
if (fPendingObject = pObject) and (@fPendingActionEvent = @pPendingActionEvent ) then
{$IFEND}
Run Code Online (Sandbox Code Playgroud)
($IFEND 而不是 $ENDIF)。但是 XE7 不会接受这种语法。
显然必须有一个技巧,确实 Delphi 2009 文档是这么说的,但是我可怜的大脑无法解决这个技巧。有人可以帮忙吗?