https://www.cnblogs.com/findumars/p/5294117.html
Delphi回調函數及其使用
1 回調函數的概述
回調函數是這樣一種機制:調用者在初始化一個(gè)對象(這里的對象是泛指,包括OOP中的對象、全局函數等)時(shí),將一些參數傳遞給對象,同時(shí)將一個(gè)調用者可以訪(fǎng)問(wèn)的函數地址傳遞給該對象。這個(gè)函數就是調用者和被調用者之間的一種通知約定,當約定的事件發(fā)生時(shí),被調用者(一般會(huì )包含一個(gè)工作線(xiàn)程)就會(huì )按照回調函數地址調用該函數。
這種方式,調用者在一個(gè)線(xiàn)程,被調用者在另一個(gè)線(xiàn)程。
消息:
消息也可以看作是某種形式的回調,因為消息也是在初始化時(shí)由調用者向被調用者傳遞一個(gè)句柄和一個(gè)消息編號,在約定的事件發(fā)生時(shí)被調用者向調用者發(fā)送消息。
這種方式,調用者在主線(xiàn)程中,被調用者在主線(xiàn)程或者工作線(xiàn)程中。
Delphi事件模型:
在Delphi的VCL中有很多可視化組件都是使用事件模型,例如TForm的OnCreate事件,其原理是:在設計時(shí)指定事件函數,在運行時(shí)事件觸發(fā),則會(huì )調用在設計時(shí)指定的事件函數。
在機制上,Delphi事件模型與回調是一樣的。但具體形式有些區別,純的回調函數是全局函數的形式,而Delphi事件是對象方法的形式,即可以定義如下回調函數類(lèi)型
type
TCallBackFunc = procedure (pData: Pointer) of object;
2 回調函數的使用說(shuō)明
回調函數主要在兩個(gè)場(chǎng)合使用,第一個(gè)是某些Windows的API要求用回調函數作為其參數地址,另一種是用戶(hù)在某種特定的場(chǎng)合定義的某個(gè)函數需要使用回調函數作為其參數地址,對于用戶(hù)的定義的函數來(lái)說(shuō),一般是當調用動(dòng)態(tài)連接庫中的函數時(shí)使用。
對于使用一個(gè)回調函數主要有以下幾個(gè)步驟:
1、定義一個(gè)回調函數類(lèi)型,跟一般的函數過(guò)程的定義并沒(méi)有什么區別,但其定義必須根據需要滿(mǎn)足回調函數的函數要求,唯一的區別在于在函數或過(guò)程的定義后面必須聲明其為windows標準調用;
例:
type
THDFunction= function(I:integer;s:string):integer; stdcall;
對于過(guò)程的聲明:
type
THDProcedure=procedure(s:string); stdcall;
2、 然后根據此原形定義一個(gè)相應的函數或過(guò)程,對于這個(gè)函數或過(guò)程來(lái)說(shuō)名字沒(méi)有什么要求,對函數其參數的類(lèi)型和返回值的類(lèi)型必須和定義的回調函數類(lèi)型完全一致,對于過(guò)程來(lái)說(shuō),只需要其參數類(lèi)型一樣就可以了。
例:根據上面的函數和過(guò)程的原形定義一個(gè)相應的函數和一個(gè)相應的過(guò)程。
函數原形定義:
Function HdFunExample(k:integer,sExam:string):integer; stdcall;
過(guò)程定義:
procedure HdProExample(sExam:string);stdcall;
3、 在程序中實(shí)現此回調函數或著(zhù)過(guò)程;
Function HdFunExample(k:integer,sExam:string):integer; stdcall;
Begin
End;
procedure HdProExample(sExam:string);stdcall;
begin
end;
4、 調用過(guò)程;
回調函數一般作為系統的某個(gè)函數的入口地址;
根據調用函數的原形:
假設有如下調用函數:
function DyHdFunExample(HdFun:THDFunction;I:integer):boolean;
注:
在調用函數中通過(guò)對函數指針的處理可以直接調用回調函數(即調用函數中的那個(gè)是回調函數類(lèi)型的參數,直接操作它),使回調函數履行一定的操作。即在調用函數中實(shí)現回調函數的功能。
調用:
var
I:integer;
begin
I:=DyHdFunExample(@HdFunExample,i);
//…….
End;
3 舉例說(shuō)明
示例程序在H:/ 回調函數示例/ 目錄下面。
回調函數的使用主要在于Windows原有的API函數,但對于用戶(hù)的自定義的調用函數一般在于動(dòng)態(tài)連接庫中。常規的同一個(gè)工程下面一般不需要使用回調函數。(個(gè)人認為).。
功能大體描述:Form1中有一個(gè)Edit和一個(gè)Button,當點(diǎn)擊BUTTON時(shí)彈出FORM2,FORM2中也有一個(gè)EDIT和一個(gè)BUTTON,當點(diǎn)擊FORM2中的BUTTON時(shí),將FORM2中的EDIT的TEXT屬性賦值給FORM1中的EDIT的TEXT。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,StdCtrls;
type
TForm1 = class(TForm)
{主窗體中放一個(gè)Edit和一個(gè)Button}
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
{定義一個(gè)用于回調的過(guò)程}
procedure test(str:string);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{引用unit2}
uses unit2;
{$R *.dfm}
{回調過(guò)程的實(shí)現部分}
procedure TForm1.test(str: string);
begin
{將str值副給Edit1}
Edit1.Text:=str;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
{調用Unit2的接口方法}
CallUnit2(test);
end;
end.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
{定義一個(gè)回調函數類(lèi)型}
TFuncCallBack=procedure(str:string) of object;
TForm2 = class(TForm)
{Form2中也有一個(gè)Edit和一個(gè)Button}
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
{定義一個(gè)回調函數類(lèi)型的變量}
aFuncCallBack:TFuncCallBack;
public
{ Public declarations }
end;
{提供給Unit1調用的接口方法,注意里面的參數的類(lèi)型}
procedure CallUnit2(FuncCallBack:TFuncCallBack);
var
Form2: TForm2;
implementation
{$R *.dfm}
{接口方法的實(shí)現部分}
procedure CallUnit2(FuncCallBack:TFuncCallBack);
begin
Application.CreateForm(TForm2,Form2);
{將參數賦值給FuncCallBack}
Form2.aFuncCallBack:=FuncCallBack;
Form2.ShowModal;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
{當點(diǎn)擊Form2的按鈕時(shí)將Form2中的Edit的值傳遞給了Form1中的Edit}
{是不是很神奇?我并沒(méi)有uses Unit1,但卻改變了Form1中Edit的Text屬性}
aFuncCallBack(Edit1.Text);
ModalResult:=mrOk;
end;
end.
http://blog.csdn.net/tercel99/article/details/4624686
http://blog.csdn.net/tercel99/article/details/4622207
聯(lián)系客服