Sender是一个TObject类型的参数,它告诉Delphi哪个控件接收这个事件并调用相应的处理过程。你可以编写一个单一的事件处理句柄,通过Sender参数和IF…THEN…语句或者CASE语句配合,来处理多个构件。发生事件的构件或控件的值已经赋给了Sender参数,该参数的用途之一就在于:可以使用保留字IS来测试Sender,以便找到调用这个事件处理句柄的构件或控件的类型。例如,将表单中编辑框和标签的Click事件的处理句柄都指向表单的xxx过程,编辑框和标签对Click事件有不同的反应:
  procedure TForm1xxx(Sender:TObject);
  begin
  if(sender is Tedit) then
  showmessage(′this is a editbox′);
  if(sender is Tlabel) then
  showmessage(′this is a label′);
  end;
  Sender参数的第二个用途是结合AS操作符进行类型转换,将若干个派生于某一父类的子类强制转换成该父类。例如表单中有一个TEdit类控件和一个TMemo控件,它们实际上都派生于TcustomEdit类,如果你要为二者的某一事件提供同样处理,可以将二者事件句柄都指向自定义的过程yyy:
  Procedure TForm1.yyy(Sender:TObject);
  begin
  (sender as TcustomEdit).text:=′This is some demo text′;
  end;
  在过程中,AS操作符将TEdit类和TMemo类均强制转换成TcustomEdit类,再对TcustomEdit类的属性赋值。注意这种转换必须符合Delphi中类的层次关系。
  使用Sender参数可以通过单一过程段处理多类控件,真正体现了Delphi面向对象的重用性。

-----------------------
Delphi之Sender

Sender其实就是函数的一个参数,你看看VCL中触发事件的代码,就会发现Sender往往代表了 “事件的触发者”,或者说“这个外挂的事件处理函数的调用者”,目的是为了让事件处理函数有一个参考尤其是当一个事件处理函数挂接到多个实例时。

//看个例子
procedure THappy.MakeLove;
var
bCancel :Boolean;
bNeedBath :Boolean;
bHappy :Boolean;
begin
bCancel := False;
bNeedBath := True;

if assigned(FOnBeforeMakeLove) then
FOnBeforeMakeLove(Self, bNeedBath, bCancel);

if bCancel then Exit;
if bNeedBath then GotoBath;

bHappy := DoMakeLove(Self.Boy, Self.Girl);

if assigned(FOnAfterMakeLove) then
FOnAfterMakeLove(Self, bHappy);
end;

procedure XXXBeforeMakeLove(Sender :TObject; var ANeedBath, ACancel :Boolean);
begin
if Sender is THappy then begin
if (THappy(Sender).Boy <> me) or (THappy(Sender).Girl.Age < 16)
or (THappy(Sender).Girl.Age > 25) then
begin
ACancel := True;
end;
ANeedBath := OfCourseTrue;
end;
end;

procedure XXXAfterMakeLove(Sender :TObject; const AHappy :Boolean);
begin
if AHappy then
begin
ShowMessage('爽歪歪...');
end
else begin
ShowMessage('555...');
end;
end;

-------

这个东西感觉还是比较抽象的。需要慢慢的细细体会。
从理论上讲Sender是一个四个字节的指针变量,里面存放的指针内容是(堆)栈中对象实体的首字节地址。我们在每次在设计APP的时候,会在Object Inspector里面双击事件属性来建立我们需要的代码,以完成预期的功能。当我们进行双击的时候,Delphi的IDE(Integreted Development Environment)会为我们自动建立与事件属性对应的过程,例如,当我们双击Form1变量的OnClick属性时,IDE会自动在TForm1类 的初始化部分创建如下的代码:
procedure TForm1.Form1Click(Sender:TObject);
同时在实现部分创建上述过程的框架,如下:
procedure TForm1.Form1Click(Sender:TObject);
begin
//初始情况下,这里并没有任何代码!
end;
然后我们在程序中可以调用这个建立好的方法,例如我们在窗体上的Button1的OnClick方法中执行如下代码:
...
Self.Form1Click(Button1);
...
同时,我们假设在Form1Click中代码如下:
...
if Sender=Button1 then
ShowMessage(TButton(Sender).Caption); //这里在判断条件为真的情况下使用强制转换
...
可以看到在代用Form1Click时,为其传递的Sender参数可以自己定义,因此严格来讲Sender参数并不代表真正触发此事件对应方法的对象,确切的说应该是用户指定的触发此事件对应方法的对象!

Sender表示触发当前事件代码的对象,而Self才表示当前方法指针指向的方法所属的对象
例如对于TForm的对象Form1,起OnClick事件中包含参数Sender,如下

procedure TForm1.FormClick(Sender:TObject);
这里的FormClick实际是Delphi的IDE在设计期为你在窗口类的初始化未命名部分自动建立的方法,但他的可见性是Pulished的,因此具有RTTI信息!!!!

在运行期间,当前的方法指针FClick指向的方法属性(即事件)OnClick所属于的对象为TForm1的实例Form1,因此Self代表的就是对 象Form1,而触发这个事件的对象不一定是Form1,有可能是Button1,所以Sender需要进行判断。你可以在Button1的 OnClick事件中调用如下代码:
Form1.OnClick(Button1);
这个时候在Form1的OnClick事件中对Sender进行判断就是Button1,而不是Form1了!

需要注意的是,由于Sender的类型为TObject,因此实际使用的时候最好进行类型转换!!!!使用As运算符!!!!

Delphi中Sender对象的知识的更多相关文章

  1. 关于delphi 中 Sender的学习

    sender是 事件的触发者,我发现所有的组件的事件 基本上都是 传Sender. 示例效果图: 代码: 接着来,既然TButton是个类,且publish哪里有事件,我们也可以看看这个事件的原型.

  2. delphi 中判断对象是否具备某一属性

    Uses   TypInfo;         {$R   *.dfm}         procedure   TForm1.Button1Click(Sender:   TObject);     ...

  3. Delphi中的Sender:TObject对象解析

    Delphi中的Sender:TObject对象解析 procedure TForm1.Button1Click(Sender: TObject); begin end; 解析:Procedure是过 ...

  4. Delphi中的Sender:TObject对象解析转载

    https://blog.csdn.net/jl_tiny/article/details/24376661 Delphi中的Sender:TObject对象解析 procedure TForm1.B ...

  5. 关于 Delphi 中的Sender和易混淆的概念(转)

    /////////////////////////////////////////////////////// Delphi 中Sender对象的定义///////////////////////// ...

  6. Delphi中使用比较少的一些语法

    本文是为了加强记忆而写,这里写的大多数内容都是在编程的日常工作中使用频率不高的东西,但是又十分重要. ---Murphy 1,构造和析构函数: a,构造函数: 一般基于TComponent组件的派生类 ...

  7. 转:Delphi中使用比较少的一些语法

    http://www.cnblogs.com/Murphieston/p/5577836.html 本文是为了加强记忆而写,这里写的大多数内容都是在编程的日常工作中使用频率不高的东西,但是又十分重要. ...

  8. Delphi引用C对象文件

    C语言应用非常广泛,并在世界各地拥有大量的代码库.这些代码库与Delphi的可比性较小,因此如果我们无需转换为Delphi代码而可以直接使用这些库的部分代码就完美了.幸运的是,Delphi允许连接到C ...

  9. Delphi引用C对象文件(转)

    源:http://blog.csdn.net/henreash/article/details/7357618 C语言应用非常广泛,并在世界各地拥有大量的代码库.这些代码库与Delphi的可比性较小, ...

随机推荐

  1. 论文翻译第二弹--用python(或Markdown)对论文复制文本进行处理

    图中这种论文你想进行文本复制放入翻译软件进行翻译时,会发现是这种形式: 句子之间是断开的,这时普遍的方法,也是我之前一直用的方法就是打开一个文档编辑器,复制上去后一行行地继续调整.昨天不想这样了,就打 ...

  2. Hibernate学习笔记一

    1 框架体系结构 2 hibernate入门 2.1 ORM框架 Hibernate是一个数据持久化层的ORM框架. Object:对象,java对象,此处特指JavaBean Relational: ...

  3. Uber优步北京第四组奖励政策

    优步北京第四组: 定义为2015年7月20日至今激活的司机(以优步后台数据显示为准) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全国版最新最详细 ...

  4. androd hook acitivity 启动流程,替换启动的activity(Android Instrumentation)

    前言:如果程序想要知道有activity启动,如果想要拦截activity,然后跳转到指定的activity怎么办? 我们看下ActivityThread 里面: private Activity p ...

  5. linux 中文输出

    #include <stdio.h> #include <stdlib.h> #include <string> #include <fstream> ...

  6. 利用Powershell查询AD中账号属性

    标签:AD账号信息 最后登录时间 最后修改密码.SID 账号SID 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://hubuxcg ...

  7. Mate20兼容性如何?WeTest带你抢先测!

    自从九月份 iPhone XS 系列发布后,WeTest团队迅速入库了iPhone XS和iPhone XR设备,十月份国内巨头华为也重磅推出了一款“Mate 20”设备,让下半年的国内手机市场又热闹 ...

  8. YUM本地源制作与yum网络版仓库

    1.修改本机上的YUM源配置文件,将源指向自己 cd /etc/yum.repos.d/ 备份原有的YUM源的配置文件 rename .repo .repo.bak * rename CentOS-M ...

  9. python操作字符串内容并重新输出

    今天在做一个函数的作业,题目如下: 编写一个函数实现大写转小写,小写变大写,并且转换为镜像字符串,并且将字符串变为镜像字符串. 例如:’A’变为’Z’,’b’变为’y 示范字符串: ”sdSdsfdA ...

  10. 项目实战:BBS+Blog项目开发

    01-博客系统之功能需求 02-博客系统之表结构设计1 03-博客系统之表结构设计2 04-博客系统之表结构设计3 05-博客系统之表结构设计4 06-博客系统之表机构设计5 07-博客系统之创建系统 ...