Delphi回调函数及其使用
Delphi回调函数及其使用
1 回调函数的概述
回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象、全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的函数地址传递给该对象。这个函数就是调用者和被调用者之间的一种通知约定,当约定的事件发生时,被调用者(一般会包含一个工作线程)就会按照回调函数地址调用该函数。
这种方式,调用者在一个线程,被调用者在另一个线程。
消息:
消息也可以看作是某种形式的回调,因为消息也是在初始化时由调用者向被调用者传递一个句柄和一个消息编号,在约定的事件发生时被调用者向调用者发送消息。
这种方式,调用者在主线程中,被调用者在主线程或者工作线程中。
Delphi事件模型:
在Delphi的VCL中有很多可视化组件都是使用事件模型,例如TForm的OnCreate事件,其原理是:在设计时指定事件函数,在运行时事件触发,则会调用在设计时指定的事件函数。
在机制上,Delphi事件模型与回调是一样的。但具体形式有些区别,纯的回调函数是全局函数的形式,而Delphi事件是对象方法的形式,即可以定义如下回调函数类型
type
TCallBackFunc = procedure (pData: Pointer) of object;
2 回调函数的使用说明
回调函数主要在两个场合使用,第一个是某些Windows的API要求用回调函数作为其参数地址,另一种是用户在某种特定的场合定义的某个函数需要使用回调函数作为其参数地址,对于用户的定义的函数来说,一般是当调用动态连接库中的函数时使用。
对于使用一个回调函数主要有以下几个步骤:
1、定义一个回调函数类型,跟一般的函数过程的定义并没有什么区别,但其定义必须根据需要满足回调函数的函数要求,唯一的区别在于在函数或过程的定义后面必须声明其为windows标准调用;
例:
type
THDFunction= function(I:integer;s:string):integer; stdcall;
对于过程的声明:
type
THDProcedure=procedure(s:string); stdcall;
2、 然后根据此原形定义一个相应的函数或过程,对于这个函数或过程来说名字没有什么要求,对函数其参数的类型和返回值的类型必须和定义的回调函数类型完全一致,对于过程来说,只需要其参数类型一样就可以了。
例:根据上面的函数和过程的原形定义一个相应的函数和一个相应的过程。
函数原形定义:
Function HdFunExample(k:integer,sExam:string):integer; stdcall;
过程定义:
procedure HdProExample(sExam:string);stdcall;
3、 在程序中实现此回调函数或着过程;
Function HdFunExample(k:integer,sExam:string):integer; stdcall;
Begin
End;
procedure HdProExample(sExam:string);stdcall;
begin
end;
4、 调用过程;
回调函数一般作为系统的某个函数的入口地址;
根据调用函数的原形:
假设有如下调用函数:
function DyHdFunExample(HdFun:THDFunction;I:integer):boolean;
注:
在调用函数中通过对函数指针的处理可以直接调用回调函数(即调用函数中的那个是回调函数类型的参数,直接操作它),使回调函数履行一定的操作。即在调用函数中实现回调函数的功能。
调用:
var
I:integer;
begin
I:=DyHdFunExample(@HdFunExample,i);
//…….
End;
3 举例说明
示例程序在H:/ 回调函数示例/ 目录下面。
回调函数的使用主要在于Windows原有的API函数,但对于用户的自定义的调用函数一般在于动态连接库中。常规的同一个工程下面一般不需要使用回调函数。(个人认为).。
功能大体描述:Form1中有一个Edit和一个Button,当点击BUTTON时弹出FORM2,FORM2中也有一个EDIT和一个BUTTON,当点击FORM2中的BUTTON时,将FORM2中的EDIT的TEXT属性赋值给FORM1中的EDIT的TEXT。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,StdCtrls;
type
TForm1 = class(TForm)
{主窗体中放一个Edit和一个Button}
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
{定义一个用于回调的过程}
procedure test(str:string);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{引用unit2}
uses unit2;
{$R *.dfm}
{回调过程的实现部分}
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
{定义一个回调函数类型}
TFuncCallBack=procedure(str:string) of object;
TForm2 = class(TForm)
{Form2中也有一个Edit和一个Button}
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
{定义一个回调函数类型的变量}
aFuncCallBack:TFuncCallBack;
public
{ Public declarations }
end;
{提供给Unit1调用的接口方法,注意里面的参数的类型}
procedure CallUnit2(FuncCallBack:TFuncCallBack);
var
Form2: TForm2;
implementation
{$R *.dfm}
{接口方法的实现部分}
procedure CallUnit2(FuncCallBack:TFuncCallBack);
begin
Application.CreateForm(TForm2,Form2);
{将参数赋值给FuncCallBack}
Form2.aFuncCallBack:=FuncCallBack;
Form2.ShowModal;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
{当点击Form2的按钮时将Form2中的Edit的值传递给了Form1中的Edit}
{是不是很神奇?我并没有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
Delphi回调函数及其使用的更多相关文章
- Delphi回调函数的使用-例子
Delphi回调函数的使用-例子 功能大体描述:Form1中有一个Edit和一个Button,当点击BUTTON时弹出FORM2,FORM2中也有一个EDIT和一个BUTTON,当点击FORM2中的B ...
- 转:Delphi 回调函数及例子
http://anony3721.blog.163.com/blog/static/5119742010866050589/ { http://anony3721.blog.163.com/blog/ ...
- delphi回调函数
文章来源: http://anony3721.blog.163.com/blog/static/5119742010866050589/ 一.主单元 unit UnMain; interface us ...
- delphi 回调函数
program Project2; {$APPTYPE CONSOLE} uses SysUtils; type //定义一个对象事件方法 TCallbackFunc = function (i: I ...
- delphi回调函数高级应用
用法一 Type TProc=procedure() of object; procedure Callback(proc:TProc); begin ... end; procedure mypro ...
- Delphi对象变成Windows控件的前世今生(关键是设置句柄和回调函数)goodx
----------------------------------------------------------------------第一步,准备工作:预定义一个全局Win控件变量,以及一个精简 ...
- DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)
函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...
- 终于懂了:Delphi消息的Result域出现的原因——要代替回调函数的返回值!(MakeObjectInstance不会帮助处理(接收)消息回调函数的返回值)
MakeObjectInstance应该不会帮助处理(接收)消息回调函数的返回值,可是有时候又确实需要这个返回值,这可怎么办呢?我是看到这段文字的时候,想到这个问题的: 当WM_PAINT不是由Inv ...
- [教程]Delphi 中三种回调函数形式解析
Delphi 支持三种形式的回调函数 全局函数这种方式几乎是所有的语言都支持的,类的静态函数也可以归为此类,它保存的只是一个函数的代码起始地址指针( Pointer ).在 Delphi 中声明一般为 ...
随机推荐
- 演练5-1:Contoso大学校园管理1
**演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...
- jsp各部分编码的含义
服务器JSP编码 pageEncoding 是jsp文件本身的编码, 第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,(jsp文件的编码,pageEncoding是 ...
- 盘点:#AzureChat - 虚拟机和自动伸缩
感谢大家跟 Corey Sanders 和 Stephen Siciliano 一起参加本次 #AzureChat.我们很高兴能借这次在线讨论的机会,倾听各位社区成员对我们最受欢迎的两个主题的意见 - ...
- C#Windows的HelloWorld
在MSDN中找到Form类:MSDN-->.NET开发-->.NET Framework SDK 2.0-->Class Library Reference -->System ...
- linux 解决Ubuntu编译内核uImage出现问题“mkimage” command not found - U-Boot images will not be built问题
解决Ubuntu编译内核uImage出现问题“mkimage” command not found - U-Boot images will not be built问题 http://www.lin ...
- UVA 11292 - The Dragon of Loowater (water)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=sh ...
- 安装windows7导致Ubuntu启动项消失的问题的解决
系统原来是Ubuntu14,前两天安装win7后,启动直接是win7.也就是Ubuntu的启动项消失了. 在windows下尝试非常多方法,都以失败告终,最后选择Ubuntu下boot-repair软 ...
- UVa 657 掷骰子
意甲冠军:有一个大图.每个像素是格孩子只可能是 . * X 三种.代表背景.玻色子.色子点. 两格子是邻近或在通信,当且仅当两个格儿子*要么X.且具有共同的边,这是上下左右四个方向,斜过,即四连块. ...
- EasyUI - DateBox组件
效果: html代码: <input type ="text" id ="box" /> JS代码: $(function () { //设置返回格 ...
- Eclipse用法和技巧十一:分栏显示
在编码的时候,有时候需要同时看到两个文件的代码.或者在代码走读的时候,能同时看到两个文件的代码能加快我们对代码的理解.来看看如何在eclipse中同时显示两个文件的代码. 步骤一:拖住一 ...