2

试图将AsyncCalls集成到我的一个 Delphi 7 项目中,我还不能调用一个类的无参数过程。

我想做的事:

TMyForm = class(TForm)
private
    procedure TestCalculation;
    procedure RunTest;
end;

var
  TestCall: IAsyncCall;

procedure TMyForm.RunTest;
begin
  TestCall := AsyncCall(TestCalculation);
end;

这是不可能的,导致错误 E2036 需要变量(当您尝试获取表达式或常量的地址时会出现此错误消息。)。

只要我的过程具有像WaitForIt中的过程这样的参数,它就可以实现。
此外,a 是可能的,LocalAsyncCall但我并不总是想声明本地过程。

如果我将其设为静态(即procedure TestCalculation不是procedure TMyForm.TesCalculation),也可以调用此过程。然后我可以成功调用RunTestCall := AsyncCall(@TestCalculation, []);但这不适用于属于的过程TMyForm

问题

如何在我的示例 ( TestCalculation) 中使用 AsyncCalls 从我的类中的另一个过程调用无参数类过程?

4

1 回答 1

4

AsyncCall期望您将传递一个接收一个参数的过程。如果你不想传递参数,只需添加一个并忽略它。

procedure TestCalculation(IgnoreMe: Integer);
....
TestCall := AsyncCall(TestCalculation, 0);

您可以编写一个适配器来使调用者的代码更清晰:

type
  TAsyncCallParameterlessProc = procedure of object;

function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall; overload;

......

type
  TAsyncCallParameterlessProcAdapter = class
  private
    FProc: TAsyncCallParameterlessProc;
  public
    constructor Create(Proc: TAsyncCallParameterlessProc);
    procedure IntegerProc(IgnoreMe: Integer);
  end;

{ TAsyncCallParameterlessProcAdapter }

constructor TAsyncCallParameterlessProcAdapter.Create(
  Proc: TAsyncCallParameterlessProc);
begin
  inherited Create;
  FProc := Proc;
end;

procedure TAsyncCallParameterlessProcAdapter.IntegerProc(IgnoreMe: Integer);
begin
  try
    FProc;
  finally
    Free;
  end;
end;

function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall;
var
  Adapter: TAsyncCallParameterlessProcAdapter;
begin
  Adapter := TAsyncCallParameterlessProcAdapter.Create(Proc);
  Result := AsyncCall(Adapter.IntegerProc, 0);
end;

使用该适配器,您问题中的代码将编译并工作。

由于 AsyncCalls 已停止使用,并且不会再次修改,因此您可以轻松地修改该代码以支持您想要的用法。

我个人会修改AsyncCalls并添加另一个子类TInternalAsyncCall来完成这项工作。

作为一个非常肮脏的黑客,这将起作用:

type
  TAsyncCallParameterlessProc = procedure of object;

function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall; overload;

.....

function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall;
begin
  Result := AsyncCall(TAsyncCallArgIntegerEvent(Proc), 0);
end;

TAsyncCallArgIntegerEvent这依赖于整数参数在易失性寄存器中传递的事实。因此,当框架通过0时,您的程序不会从寄存器中读取它。

于 2012-12-13T13:53:23.647 回答