有谁能够给我讲讲回调函数?(50分)

  • 主题发起人 主题发起人 datoncg
  • 开始时间 开始时间
D

datoncg

Unregistered / Unconfirmed
GUEST, unregistred user!
我每次见了回调函数的解释老是不明白!——<br>“回调函数就是能对一系列系统内部元素执行给定操作的API函数”<br>有谁能够举个实例来说明,并加上说明!
 
例如我想在托盘中加入图标,响应鼠标事件,<br>向windows注册时提交回调函数<br>
 
回调函数也就是由操作系统调用的函数!一般在高级WINDOWS SDK编程序的时候会用到!<br>你需要形式上声明一个WINDOWS所要求的函数,然后把函数的地址传给WINDOWS,也就是让<br>WINDOWS知道你需要执行的指令的地址,当某种特定的情况下,WINDOWS会调用你写的这个函数!<br>从而使你获得控制权.例如:<br>HHOOK SetWindowsHookEx(<br>&nbsp; &nbsp; int idHook, // type of hook to install<br>&nbsp; &nbsp; HOOKPROC lpfn, // address of hook procedure &lt;--此处就要求给出一个回调函数的地址给OS;<br>&nbsp; &nbsp; HINSTANCE hMod, // handle of application instance<br>&nbsp; &nbsp; DWORD dwThreadId // identity of thread to install hook for <br>&nbsp; &nbsp;);<br>这个API函数允许程序员监视一些特定的系统事件!了解很有用的哦![blue][/blue]
 
简单的说:回调函数一般不会被显示的调用,它是在符合某种条件时被操作系统调用的,一般有一个注册<br>函数。注册函数相当于告诉操作系统:等XXXXX(来了)你就给我干这个!![:)]
 
通俗的说:调用的函数(内部代码)需要使用自己编写的一个函数(外部代码) ,自己编写的<br>这个函数就是回调函数。<br><br>例子如下:(实现流动线的效果)<br><br>Timer1.Interval = 200;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; Counter :Byte;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure MovingDots(X,Y: Integer; TheCanvas: TCanvas); stdcall;<br>begin<br>&nbsp; Counter := Counter shl 1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Shift the bit left one<br>&nbsp; if Counter = 0 then Counter := 1; &nbsp; &nbsp; &nbsp;// If it shifts off left, reset it<br>&nbsp; if (Counter and 224) &gt; 0 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Are any of the left 3 bits set?<br>&nbsp; &nbsp; TheCanvas.Pixels[X,Y] :=clBtnFace &nbsp; // Erase the pixel<br>&nbsp; else<br>&nbsp; &nbsp; TheCanvas.Pixels[X,Y] :=clBlack; &nbsp; &nbsp;// Draw the pixel<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br>&nbsp; LineDDA(30,30,200,30,@MovingDots,LongInt(Canvas));<br>&nbsp; LineDDA(200,30,200,150,@MovingDots,LongInt(Canvas));<br>&nbsp; LineDDA(200,150,30,150,@MovingDots,LongInt(Canvas));<br>&nbsp; LineDDA(30,150,30,30,@MovingDots,LongInt(Canvas));<br>end;<br><br>以上的LineDDA就是我们说得内部函数,而它调用的MovingDots就是自己定义的外部函数,<br>也就是回调函数。<br><br>
 
哦学习。
 
普通函数是自己写自己调用,如果函数是自己写,由别人(操作系统)来调用,这个函数就叫回调函数
 
我看过一篇文章:回调函数就是能对一系列系统内部元素执行给定操作的API函数<br>,例如能对所有同类窗口进行操作的函数。但还是不明白!他也有例子!<br>如:<br>function GetTitle (Hwnd: THandle; Param: Pointer): Boolean; stdcall;<br>var<br>&nbsp; Text: string;<br>begin<br>&nbsp; SetLength (Text, 100);<br>&nbsp; GetWindowText (Hwnd, PChar (Text), 100);<br>&nbsp; FormCallBack.ListBox1.Items.Add (<br>&nbsp; &nbsp; IntToStr (Hwnd) + ': ' + Text);<br>&nbsp; Result := True;<br>end;<br>procedure TFormCallback.BtnTitlesClick(Sender: TObject);<br>var<br>&nbsp; EWProc: EnumWindowsProc;<br>begin<br>&nbsp; ListBox1.Items.Clear;<br>&nbsp; EWProc := GetTitle;<br>&nbsp; EnumWindows (@EWProc, 0);<br>end;<br>在这个例子中到底哪个是回调函数?他有是怎么实现调用的?<br>他的值是怎么得到的?<br>
 
说的简单一点就相当于Event事件
 
大家都说得很明白了<br>其实简单的说真的相当于一个event时间,是满足一个条件时由系统隐含调用的<br>自己编写的函数
 
》》在这个例子中到底哪个是回调函数?他有是怎么实现调用的?<br><br>看你的例子中有如下3句:<br>&gt;function GetTitle (Hwnd: THandle; Param: Pointer): Boolean; stdcall;<br>&gt;EWProc := GetTitle;<br>&gt;EnumWindows (@EWProc, 0);<br>回调函数应该是GetTitle() &nbsp; ,执行了EWProc := GetTitle;后,<br>再由EnumWindows 这个系统API调用!<br><br>另外,用stdcall;指示符声明,以示遵循win3的调用约定! &nbsp; &nbsp;<br><br>楼上说的很好,长知识!
 
我把你的程序执行了一下(好像得到的是全部窗口),<br>其实根本就没有必要用到EWProc := GetTitle; &nbsp; <br>即你完全可以把EnumWindows (@EWProc, 0); -----&gt; EnumWindows (@GetTitle, 0);<br><br>这样会看的更明白一点! &nbsp; [:)]
 
详细请查看[red]MS SDK Help or MSDN Library[/red]!
 
说得好,详情请联系MS的开发人员 :)
 
EWProc指向的那个就是你的回调函数<br>所谓回调函数,就是你写一个函数,然后把函数地址通过API传给系统,系统在合适的时间调用<br>如上面的EnumWindows (@EWProc, 0);,系统执行的时候会遍历每个Window,并为每个Window<br>调用一次(所谓回调就体现在这里了,是系统帮你调用,而不是你自己调用)。<br>window.Handle为遍历到的那个Window的句柄,0是你传入的参数了,当然也可以是你自定义<br>的参数,比如传入某一Form的Handle,然后在执行<br>GetTitle时把Window的相关信息OutPut到Form的某一控件上等<br>当然,你也可以写自己的回调函数,就跟系统执行EnumWindows时一样做就行了。
 
Callback function with a DLL <br>learn more about function types <br>Product:Delphi all versions <br>Uploader: max kleiner &nbsp; &nbsp; &nbsp; Company: kleiner kommunikation <br>Question/Problem/Abstract:<br>how to make a DLL like a controller and how to write a callback-function with a DLL <br>Answer:Callback function with a DLL <br>----------------------------- <br>First a brief definition: A callback function is a function which you write, but is called by some other program or module, such as windows or DLL's. <br>For example a DLL (like a watchdog) controls many clients, so when a certain event occurs from the DLL that you called once, the callback function in the client is called (being passed any parameters or signals you need) and when the DLL-callback has completed, control is passed back to the controller-DLL or the client. <br><br>By the way, there is almost no possibilitie to make it more OO-like with a class, cause a callback is always an address of a standard procedure or function. <br>So the reason for this is that windows does not pass back any reference to SELF (means the instance of the class), which is used by classes when deciding which method from the instance to work with. <br><br>Let's get back to the framework and create a callback function, <br>you must first: <br><br>1. declare a function type <br>2. the function itself <br>3. define the DLL reference <br>4. then implement the function in the client <br>5. and call the DLL: <br><br>Callback example in client unit <br>----------------------------------------------- <br>&nbsp; &nbsp;interface... <br>1. TCallBackFunction = function(sig: integer):boolean; <br><br>2. function callME(sig: integer):boolean; <br><br><br>&nbsp; &nbsp;implement... <br>3. procedure TestCallBack(myCBFunction: TCallBackFunction); register; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;external('watchcom.dll'); <br>4. function callMe(sig: integer): boolean; <br>&nbsp; &nbsp;begin <br>&nbsp; &nbsp; &nbsp;{whatever you need to do, case of...} <br>&nbsp; &nbsp; &nbsp;showmessage('I was called with'+ inttostr(sig)); <br>&nbsp; &nbsp;end; <br><br>5. procedure TForm1.Button1Click(sender: TObject); <br>&nbsp; &nbsp;begin <br>&nbsp; &nbsp; &nbsp;testCallBack(callMe); &nbsp;//subscribe function in DLL <br>&nbsp; &nbsp;end; <br><br><br>Callback in the DLL <br>----------------------------------------------- <br>In the DLL you would also declare a function type and a <br>procedure (or function) itself, so use it like this: <br><br>type <br>TCallBackFunction = function(sig: integer):boolean; <br><br>procedure TestCallBack(clientFunc: TCallBackFunction); <br>var sigAlive: boolean; <br>begin <br>&nbsp; {timer stuff... <br>&nbsp; set the signal...} <br>&nbsp; if(clientFunc(55)) then sigalive := true; <br>end; <br><br>exports TestCallBack; <br><br><br>************* Simple Sequence Diagram************** <br><br>Client &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DLL <br>&nbsp; ? TestCallBack(clientFunc) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;? <br>&nbsp; ?---------------------------------------------&gt;? <br>&nbsp; ?clientFunc.callMe(sig) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;? <br>&nbsp; ?----------------------------------------------? <br>&nbsp; ?nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;? <br>&nbsp; ?true (or something to return) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? <br>&nbsp; ?---------------------------------------------&gt;? <br>&nbsp; ?nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;? <br><br>max kleiner <br><br>callback (See also ID582) <br>&nbsp;<br><br>
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
913
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部