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. JZ2440开发板:UART(串口)使用(学习笔记)

    查看UART在硬件上的信息,阅读JZ2440原理图可以看到: JZ2440开发板的UART0是可以跟USB相接的,用于打印调试,UART1,UART2两个串口用来外接模块.所以本文仅对UART0进行操 ...

  2. 北京Uber优步司机奖励政策(12月18日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. 厦门Uber优步司机奖励政策(12月14日到12月20日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. tarjan算法求最近公共祖先

    tarjian算法 LCA: LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们 ...

  5. linux (rm指令) 及误删除解决

    今天在群里看见这一幕: 看到这儿,我们学习一下 这个RM指令 rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件 ...

  6. 6、Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  7. Andorid自定义attr的各种坑

    本文来自网易云社区 作者:孙有军 在开发Andorid应用程序中,经常会自定义View来实现各种各样炫酷的效果,在实现这吊炸天效果的同时,我们往往会定义很多attr属性,这样就可以在XML中配置我们想 ...

  8. 如何用istio实现应用的灰度发布

    Istio为用户提供基于微服务的流量治理能力.Istio允许用户按照标准制定一套流量分发规则,并且无侵入的下发到实例中,平滑稳定的实现灰度发布功能. 基于华为云的Istio服务网格技术,使得灰度发布全 ...

  9. Selenium安装(二)

    安装python 安装Selenium之前首先来说一下Python,python是一门动态性语言,python的编写比较灵活,简洁,开发效率高.因此以python结合selenium来进行自动化测试. ...

  10. 166. Nth to Last Node in List

    Description Find the nth to last element of a singly linked list. The minimum number of nodes in lis ...