问题: 什么是回调函数,最好有例子! ( 积分: 49 ) <br>分类: Windows API <br> <br>来自: M16, 时间: 2002-12-23 16:22:00, ID: 1530826 <br>顺便问一句,哪里有《英雄》的盗版卖??? <br> <br>来自: withdraw, 时间: 2002-12-23 16:27:00, ID: 1530844 <br>上网down <br>type test=function(string str); <br>procedure do_function(test test1); <br>var String str1; <br>begin <br>str1:="asdad"; <br> test1(str1); <br>end <br><br>好像是这样 <br> <br>来自: jsxjd, 时间: 2002-12-23 16:38:00, ID: 1530886 <br>23. DLL和回调函数例子 <br>以下是完整的例子: <br><br>DLL 程序 <br><br>library Project2; <br><br><br>uses <br> SysUtils, <br> Classes; <br> function AddTwo(x,y:integer):integer;stdcall; <br> begin <br> Result:=x+y; <br> end; <br> function MultiTwo(x,y:integer):integer;stdcall; <br> begin <br> Result:=x*y; <br> end; <br>{$R *.RES} <br> exports AddTwo,MultiTwo; <br>begin <br>end. <br><br><br><br>调用程序 <br>unit Unit1; <br><br>interface <br><br>uses <br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, <br> StdCtrls; <br><br>type <br> TForm1 = class(TForm) <br> Button1: TButton; <br> procedure Button1Click(Sender: TObject); <br> private <br> { Private declarations } <br> public <br> { Public declarations } <br> end; <br><br>var <br> Form1: TForm1; <br><br>implementation <br><br>{$R *.DFM} <br>function AddTwo(x,y:integer):integer;stdcall;external 'project2.dll'; <br>function MultiTwo(x,y:integer):integer;stdcall;external 'project2.dll'; <br>type <br> TCallBackFun=function(x,y:integer):integer;stdcall; <br><br>function Myfun(x,y:integer;f:TCallBackFun):integer; <br>begin <br> result:=TCallBackFun(f)(x,y); <br>end; <br>procedure TForm1.Button1Click(Sender: TObject); <br>begin <br> showmessage(inttostr(MyFun(10,20,@AddTwo))); <br> showmessage(inttostr(MyFun(10,20,@MultiTwo))); <br>end; <br><br>end. <br><br> <br>来自: M16, 时间: 2002-12-23 16:49:00, ID: 1530949 <br>to jsxjd <br>你说的意思我大概明白了,但是向你这个dll中 <br>函数完全可以直接调用,为什么非要用什么回调函 <br>数呢,请进一步解释,谢谢! <br> <br>来自: wlmmlw, 时间: 2002-12-23 17:00:00, ID: 1531004 <br>把函数A做为一个参数传递给一个被调用函数B <br>这样B就可以反过来调用A了。 <br>比如B在列出一个目录下的所有子目录,如果它设置了一个回调用函数,这样它就可以在 <br>找到每个子目录的时候调用一下回调用函数来通知你,你就可以在回调用函数做某些操作。 <br><br> <br>来自: youou, 时间: 2002-12-23 17:13:00, ID: 1531061 <br>回调函数是一种特殊的引出函数,是由WINDOWDS环境直接调用的函数。 <br> 不是被应用程序调用,而是被WIN 32 DLL或其他DLL调用。 <br><br> <br>来自: vine, 时间: 2002-12-23 17:17:00, ID: 1531079 <br>可以看看<Delphi5 开发人员指南>里面的部分 <br>很多地方有这个的电子书呵 ! <br> <br>来自: pcexplorer, 时间: 2002-12-23 17:27:00, ID: 1531121 <br>回调函数很有用 <br>比如你的线程在一个单独的单元里,线程的功能是不断刷新主窗口上的进度条,如果不用回调 <br>函数那么你必须要做的是A(主单元)引用B,B引用A而且这样结构就很差,如果用了回调函数就 <br>只要A引用B就可以了。 <br>如: <br>TMyProc = procedure (iMax, iPosition: Integer); <br><br>//线程构造 <br>//FProc: Pointer; <br>constructor Create(AProc: Pointer); <br>begin <br> inherited Create(False); <br> FProc := AProc; <br>end; <br><br>procedure CallMyProc; <br>begin <br> TMyProc(FProc)(Max, Position); <br>end; <br><br>//OnExecute <br>synchronize(CallMyProc); <br>//这样主程序只要做一个函数来操纵本单元窗口上的东西就可以了 <br>procedure MyProc(iMax, iPosition: Integer); <br>begin <br> with Form1 do <br> begin <br> ProgressBar1.Max := iMax; <br> ProgressBar1.Position := iPosition; <br> end; <br>end; <br><br>//创建线程把函数地址传递到线程中,在线程中得到了地址就可以调用了, <br>//这样线程单元就完全独立开来了,不引用主窗口的单元却操纵了主窗口的东西 <br>with SomeThread.Create(@MyProc) do <br><br>//我在我的程序里经常用回调函数很有用 <br>//其实任何一个Windows程序都用到和回调函数在CreateWindow的时候就必须向Windows传递一个 <br>//函数地址,你回发现您并没有调用,但实际程序确实工作了,Why?因为Windows调用了这个函数, <br>//这个就是原理 <br> <br>来自: pcexplorer, 时间: 2002-12-23 17:32:00, ID: 1531141 <br>说了半天在给断代码吧 <br>unit Unit3; <br><br>interface <br><br>uses <br> Classes, Windows, Forms; <br><br>type <br> TMyCallBackProc = procedure (FMin, FMax, FPosition: integer); <br><br> TMyThread2 = class(TThread) <br> private <br> FProc: Pointer; <br> { Private declarations } <br> procedure SynchProcedure; <br> protected <br> procedure Execute; override; <br> public <br> constructor Create(const AProc: Pointer); <br> end; <br><br>implementation <br><br>{ TMyThread2 } <br><br>constructor TMyThread2.Create(const AProc: Pointer); <br>begin <br> FProc := AProc; <br> inherited Create(false); <br>end; <br><br>procedure TMyThread2.Execute; <br>begin <br> FreeOnTerminate := true; <br> Synchronize(SynchProcedure); <br>end; <br><br>procedure TMyThread2.SynchProcedure; <br>const <br> cMin = 0; <br> cMax = 100; <br>var <br> i: integer; <br>begin <br> if FProc <> nil then <br> for i := cMin to cMax do <br> begin <br> TMyCallBackProc(FProc)(cMin, cMax, i); <br> Sleep(100); <br> Application.ProcessMessages; <br> end; <br>end; <br><br>end. <br><br>//---------------------------------------- <br>procedure MyCallBackProc(FMin, FMax, FPosition: integer); <br>begin <br> with Form1.ProgressBar2 do <br> begin <br> Min := FMin; <br> Max := FMax; <br> Position := FPosition; <br> end; <br>end; <br><br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br> MyThread2: TMyThread2; <br>begin <br> MyThread2 := TMyThread2.Create(@MyCallBackProc); <br>end; <br> <br>来自: youou, 时间: 2002-12-23 19:05:00, ID: 1531337 <br>呵~~ <br><br>不错。。还是上面两位说得清楚明白哦。。 <br><br> <br>来自: 人在昆明, 时间: 2002-12-23 19:09:00, ID: 1531344 <br>search 了一下硬盘,找到了一个算法的,以前写的 <br>题目 是那个 著名的生小兔的问题,说一堆兔子三个月后会生一对小兔,然后每个月 <br>生一对,小兔长到三个月后每个月又可以生一对,假设都不死,按照这个规律20个月 <br>后多少只兔子。 <br>分析过程: <br>{ <br> 不知道大家发现了没有 规律如下: <br> 数学中有一个以他的名字命名的著名数列: <br> 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, …… <br> 从第三个月每个月的 兔子数目是前两个月的和 <br> 那么问题就变成了,求第 n 项 得值,那么就是一个递归而已了 <br>} <br>下面是 我的递归算法: <br>function TRabbit.RecursionRabbit(iNum: Integer): Integer; <br>var <br> I: Integer; <br>begin <br> if (iNum = 1) or (iNum = 2) then <br> Result := 1 <br> else <br> Result := RecursionRabbit(iNum - 1) + RecursionRabbit(iNum - 2) <br>end; <br> <br>来自: 人在昆明, 时间: 2002-12-23 19:11:00, ID: 1531346 <br>不好意思,看错啦,回调 去看看消息循环的那些东西吧,呵呵。 <br> <br>来自: youou, 时间: 2002-12-23 20:30:00, ID: 1531539 <br>我想给 pcexplorer 加分。。 <br>谢谢你讲得这么明白~~ <br><br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=1531533 <br>请来这领分。。。 <br><br><br><br> <br>来自: M16, 时间: 2003-01-17 11:45:00, ID: 1585907 <br>接受答案了. <br> <br>得分大富翁: pcexplorer