我是delphi的初学者,我在看例程时,经常看到sender,我不知道它的具体用法,如sender as TmenuItem,请各位大虾帮帮小弟

解决方案 »

  1.   

    简单地说,Sender可以称为触发这个事件的控键
    比如说
    Procedure TForm1.Button1Click(Sender:TObject);
    begin
       if Sender is TButton then
          showmessage((Sender as TButton).Caption)
       else
          showmessage('没有Sender')
    end;如果你这样调用
    Procedure TForm1.button2.click(sender:Tobject);
    begin
       Button1Click(nil);
    end;
    则返回'没有Sender'而如果你这样调用
    Procedure TForm1.button2.click(sender:Tobject);
    begin
       Button1Click(sender);
    end;则显示button2
    明白了吗?
      

  2.   

    as是类运算符
    表达式为 Object as Class
    返回和Object相同的类引用,Object对象必须是Class类的一个实例,或是它的派生类的一个实例,或者是nil,否则将产生异常,就象你上面写的
    sender as TmenuItem
    那么,Sender一定是TmenuItem类或它的子类的一个实例,而在我的例子中,你就不能这么写了,只能写成Sender as TButton,因为Sender是TButton的一个实例。
      

  3.   

    sender就是响应消息的那个control,建议你用tbutton(sender).caption不要用
    (sender as tbutton).caption,太慢
      

  4.   

    as操作符做的事情比强行转换要多得多啊,
    建议你看看<<深入delphi com编程>>
      

  5.   

    sender就是发出消息的那个control,
    在拖放编程中是否接受,经常要判断sender类型
      

  6.   

    我也聊一聊:
        事件处理程序通常有一个Object类型的sender 参数,这意味着Sender对象可以属于任何类,因为每个类都是从Tobject类派生出来的。
    这种方式的缺陷就是:在使用对象上进行操作时必须知道它的数据类型。事实上,Object类型的变量或参数只能应用于由TObject 定义的对象和属性。
    例如:(sender as tbutton).caption 做类型转换
    to: stanely(俺是邢她汉子) 
    谢谢你的方法。
      

  7.   

    以前收藏的一点东西:
    回复人: manboo(横刀) (  ) 信誉:100  2002-3-27 19:46:01  得分:20    在大多数组件的事件里面sender 代表,组件自己,但是也有一些将sender
    指向其他的对象,关键看什么,Delphi 使用sender主要是为了使代码复用性好些!
    如:
    一个窗体上有两个Edit框Edit1,Edit2,你想实现输入的字符大写:
    procedure UpCaseInput(Sender:TObject;var Key:char);
    begin
     if Sender is TEdit then
      begin
      Key:=UpCase(Key);
      end;end; 
    你只要将:UpCaseInput赋给
    Edit1.OnKeyPress 和Edit2.OnKeyPress
    就行了没必要写两次了!  
     
      as是类型转换,如果类型不匹配会引发例外。这是一种比较安全的强制类型转换。
    比如
    Sender as TEdit //将Sender转化为TEdit类型。 
     
    回复人: manboo(横刀) (  ) 信誉:100  2002-3-27 19:56:54  得分:20  
     
     
      Delphi引入Sender 主要是为了代码的复用性;看下面的例子
    窗体上有两个Edit,Edit1,Edit2,使用sender,为了两个Edit实现字符大写的功能:
    procedure UpCaseChar(Sender:TObject;Key:Char);
    begin
     if Sender is TEdit then//判定是否为TEdit 控件
        begin
         key:=UpCaseKey;
        end;
    end;
    只要将Edit1,Edit2的OnKeyPress事件等于UpCaseChar就可以了,而不要为两个控件分别写,这个例子不是太好,这样说比较好,如果你要对一组同类形(或者是有相同父类的)
    的组件进行相同的事件处理,使用Sender 可以减少工作量的!
    Is 用来类型判定,是非常好的实时操作莩,As用于安全类型转换,而不是Txx(Y)这样的强制性转换! 
     
     
    Top 
     
     回复人: xxmmmx(踢踏) (  ) 信誉:100  2002-3-27 20:07:56  得分:40  
     
     
      我找到的一些资料,关于Sender的,挺不错的,共享。
    在 Delphi1.0的user's guide 中 用到 Sender这个通用的prarmeter有时要用 
    sender as ClassRef 的形式
         有时只用Sender就可以, 如          with Sender as TButton do
              begin
                Caption := '&Ok';
                OnClick := OkClick;
              end;          if Sender = Button1 then
                AboutBox.Caption := 'About ' + Application.Title
              else AboutBox.Caption := ;     也有人写成          case TButton(sender).Tag of     以上这三种形式到底适用在什麽情况下呢?     这是个观念的问题, 我尝试解释看看, 不对与不足的地方还请其他网友不吝指
    正:     (Sender as TButton) 与 TButton(Sender) 都是 Typecasting,只是语法不同
    罢了, 因此, 写成 (Sender as
         TButton).Caption := 'Test';或者 TButton(Sender).Caption := 'Test'; 结
    果都一样     针对个别物件个别事件撰写事件处理程序, 并不需判定 Sender为何, 因为很明
    显的 Sender
         便是这个正在撰写的物件, 但是在多个物件共用一个事件处理程序的情况下, 
    Sender 是谁(谁发生OnClick
         事件)的判断就有其必要性     if Sender = Button1 的写法是直接判定Sender是不是 Button1这个物件, 但
    是如果按钮有 64 个, 写 64 个 if
         叙述恐怕会累死人的...     因此, 以类别的判定取代个别物件的副本(instance)的判定, 应是比较简明的
    作法, 於是, 我们可以写成
         Sender is TButton, 为真时, 以上述型别转换的方式 --- 
    TButton(Sender).XXXX 撰写, 就可以大辐简化程式,
         毕竟,同属 TButton 的物件, 都有相同的属性(属性值不一定相同), 不是吗?     值得注意的是, Sender is (Class Name) 的 Class Name 判断是会牵涉到父阶
    的继承关系的, 例如: Button1 是
         Button,Button2是 TBitBtn, 这样的话:Button1 is TButton 为真, Button2 
    is TButton 也是真, 因为TBitBtn 继承自
         TButton, 也就是说, 球是球, 篮球也是球. 应用这个观念, 下列的程式:          if ActiveControl is TDBEdit then
                (ActiveControl as TDBEdit).CutToClipboard
              else if ActiveControl is TDBMemo then
                (ActiveControl as TDBMemo).CutToClipboard;     如果改成:          if ActiveControl is TCustomMemo then
                TCustomMemo(ActiveControl).CutToClipboard;     程式的执行效率就更好了, 因为 TDbEdit 与 TDbMemo 的共同父阶是 
    TCustomMemo, 而 TCustomMemo
         也有 CutToClipboard 方法     此外, (Sender as TButton) 在型别转换时若发生错误,会举发例外讯息, 而
         TButton(Sender)则强制转型不会举发例外报告. 像是下例的写法,虽然没有例
    外讯息,
         但在逻辑上毕竟是不正确的; 换句话说, 语法错误是没有, 但潜藏的错误仍然
    危险:     // 假设 Sender 事实上是 TButton 型的物件     TPanel(Sender).BevelWidth := 2;     所以, 有一些人主张保险起见应该写成:     // 假设 Sender 事实上是 TButton 型的物件     (Sender as TPanel).BevelWidth := 2;     以便在不正确型别强转换时提示错误的发生.     但话说回来了, 型别转换到底合不合理是程式发展人员的责任, 将 TButton转
    型成TPanel就说不通.
         不管用哪一种写法, 在转换前作一下判断是应该的,所以, 您可能会常看到类似
    如下的写法:     if ActiveControl is TCustomMemo then
           TCustomMemo(ActiveControl).CutToClipboard;     用意即在先作一次判断. 当然, 交给例外处理机制接管也行, 但毕竟是打扰了
    程式的执行流程,
         有点令人讨厌, 我是认为 Except 应该是在「承认理性是局部的」与「程式可
    读性」等两个前提下的後援,
         可能的话, 能在事前加以判断是比较好的.     准此, 则下列的写法就很经典了:       if Sender is TPanel then
             (Sender as TPanel).BevelWidth := 2;