相关疑难解决方法(0)

Delphi:测试事件处理程序分配

我想在构造函数中分配一个事件处理程序,如果它没有分配.因此,我想删除析构函数中最终分配的事件处理程序.我编写的代码如下,但无法编译.

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.但我不希望这作为解决方案.

delphi event-handling

8
推荐指数
2
解决办法
1961
查看次数

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

我想创建一个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其删除,但我想确保我的后代类也将支持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 …
Run Code Online (Sandbox Code Playgroud)

delphi oop windows-services

4
推荐指数
1
解决办法
166
查看次数

如何比较事件及其避免E2035和E2036的相应程序?

我正在尝试检查是否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

delphi events compiler-errors delphi-2007

3
推荐指数
1
解决办法
94
查看次数

依赖于版本的编译 - $ENDIF 和 $IFEND

我似乎处于 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 文档是这么说的,但是我可怜的大脑无法解决这个技巧。有人可以帮忙吗?

delphi

2
推荐指数
1
解决办法
1092
查看次数