尝试将AsyncCalls集成到我的一个Delphi 7项目中,我还没有能够调用类的无参数过程。
我想做什么:
TMyForm = class(TForm)
private
procedure TestCalculation;
procedure RunTest;
end;
var
TestCall: IAsyncCall;
procedure TMyForm.RunTest;
begin
TestCall := AsyncCall(TestCalculation);
end;
这是不可能的,导致错误E2036需要变量(当您尝试获取表达式的地址或常量时会出现此错误消息。)。
只要我的程序具有此example中的WaitForIt
程序等参数,就可以
此外,LocalAsyncCall
可能有用,但我并不总是想要声明本地程序。
如果我将其设为静态(即procedure TestCalculation
而不是procedure TMyForm.TesCalculation
),也可以调用此过程。然后我可以成功调用RunTestCall := AsyncCall(@TestCalculation, []);
但这不适用于属于TMyForm
的过程。
问题
如何在我的示例(TestCalculation
)中使用AsyncCalls从我的类中的另一个过程调用无参数类过程?
答案 0 :(得分: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
时,您的程序不会从寄存器中读取它。