自己怎么写回调函数?(100分)

  • 主题发起人 主题发起人 GoodYes
  • 开始时间 开始时间
G

GoodYes

Unregistered / Unconfirmed
GUEST, unregistred user!
问题是这样的,假设我写了一个A函数完成特定操作,调用A函数时需要传入一个“过程”参数,当A函数完成后调用那个传入的“过程”参数,然后那个“过程”参数再完成一些操作。现在我不知道那个“过程”如何定义,如何传递给A函数。

这个问题好比API函数的回调,如果把我的问题比喻成API回调的话,就是说我不知道该怎么定义API函数需要的回调,也不知道如何传给API。

还有,我想实现的效果好比 线程类 完成后会调用传递给线程类的 OnTerminate 过程一样。

不知道我说明白了没有?
 
这个看我的,给你写了个demo版程序
 
unit Unit1;
{By 月夜风筝,icc}

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//关于两数A,B的二元运算,返回同类型
TCallBackFunc = function (const A, B: Integer): Integer;


var
Form1: TForm1;

implementation

{$R *.dfm}

{下面的四个函数给出了支持回调接口的四种运算,即:加、减、除、平方和
注:从回接口 “TCallBackFunc” 可以看出,它是关于二元整型的运算符,返回整型
这几个函数都符合接口规范,因此可被随意回调
这几个函数可以看作是“数据运算插件”,它们的开发可由多人共同进行
这几个函数充当了具体的回调执行代码
}

function Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;

function Minus(const A, B: Integer): Integer;
begin
Result := A - B;
end;

function Multi(const A, B: Integer): Integer;
begin
Result := A * B;
end;

function Square(const A, B: Integer): Integer;
begin
Result := A * A + B * B;
end;

{这里定义了回调,比较重要的接口}
function Calc(const OP: TCallBackFunc
const X, Y: Integer): string;
begin
Result := IntToStr(OP(X, Y));{这里的“OP”就是回调的定义之地}
{ 更典型的写法可能是如下形式,VCL中有大量类似代码
Result := -1;
if Assigned(OP) then
Result := IntToStr(OP(X, Y));
}
end;


procedure TForm1.btn1Click(Sender: TObject);
const
A = 2;
B = 3;
var
s : string;
begin
s := Calc(Add, A, B)
{这里激活了回调,以下同}
s := Format('"Add&quot
of %0:d and %1:d is : %2:s', [A, B, S]);
ShowMessage(s);

s := Calc(Minus, A, B);
s := Format('"Minus&quot
of %0:d and %1:d is : %2:s', [A, B, S]);
ShowMessage(s);

s := Calc(Square, A, B);
s := Format('"Square Plus&quot
of %0:d and %1:d is : %2:s', [A, B, S]);
ShowMessage(s);
end;

end.
 
小结:
1、定义回调接口
2、定义回调代码
3、绑定并激活回调事件
 
楼上的镇厉害,还能怎样用.~!!!
 
只要开发过控件的,对这些东西绝对了如指掌
 
非常感谢 icc !我懂了。
 
多人接受答案了。
 
icc 朋友,现在又出现了一个问题

function Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;

这个函数出现在类外没有问题,但是如果类似这样就出错
function TForm1.Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;

我把你的
TCallBackFunc = function (const A, B: Integer): Integer;
改成了
TCallBackFunc = function (const A, B: Integer): Integer of object;
就可以了,请问这样对吗?为什么要这样呢?
 
这么写是对的,在对象里,就是应该这么用
原因是所有对象的回调方法都是4字节的方法,2个字节用于函数地址,另2个字节用于对象本身的地址
加上of object正是这种含义,所以就对了!
 
你说的“在对象里”是指的在类实例中吗?例如在TForm1类的Form1实例中(不好意思,我刚学,对象、类什么的我还搞不太清)。
是不是说,给那个 需要回调的函数(例子中的Calc) 传递的回调(Add 等计算函数) 如果是在对象(指的是TForm1的实例)中,那么回调的声明(TCallBackFunc)必须加 of object ?
反之,如果被回调的函数在类外,就不用加 of object 。
我说得对吗?
还有,看Delphi线程类的 OnTerminate 属性的声明是 TNotifyEvent = procedure(Sender: TObject) of object

而且很多组件的事件都带有 Sender 参数,这个起到什么作用?自写回调函数是否建议添加上?
 
后退
顶部