什么是回调函数,最好有例子!(49分)

  • 主题发起人 主题发起人 M16
  • 开始时间 开始时间
M

M16

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