我是delphi的初学者,我在看例程时,经常看到sender,我不知道它的具体用法,如sender as TmenuItem,请各位大虾帮帮小弟
解决方案 »
- 求助:ListView_GetSubItemRect 在Delphi中编译报错:Undeclared identifier: 'ListView_GetSubItemRect'
- 大虾,救命呀
- 请问用什么可以较方便地编辑注册表?
- 用程序获得一个表的字段名、字段类型、字段长度,想拼制一个插入这个表的语句SQL,该怎么做?
- 暂存依次搜索到的数据集d问题
- 请问如何实现网页风格按钮?
- 程序任务栏指示图表的实现-(例如输入法)delphi
- 关于在STRINGGRID中的cell中画TDBEIDT控件的问题,高手请进!有原程序
- 有学号、题号、每一题的难度、区分度、答题反应时间(每个学生回答每道题的时间)等字段,如何建table才合适,并且可以计算出每一题的答对次数,如何进行编程,请赐教!最好有源代码。本人有急用!就要交毕业设计了!!1
- 用DELPHI 5 实现ISAPI编程
- 如何屏蔽键盘上某个按键
- 谁知道Installshield Express 3.53的激活码???
比如说
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
明白了吗?
表达式为 Object as Class
返回和Object相同的类引用,Object对象必须是Class类的一个实例,或是它的派生类的一个实例,或者是nil,否则将产生异常,就象你上面写的
sender as TmenuItem
那么,Sender一定是TmenuItem类或它的子类的一个实例,而在我的例子中,你就不能这么写了,只能写成Sender as TButton,因为Sender是TButton的一个实例。
(sender as tbutton).caption,太慢
建议你看看<<深入delphi com编程>>
在拖放编程中是否接受,经常要判断sender类型
事件处理程序通常有一个Object类型的sender 参数,这意味着Sender对象可以属于任何类,因为每个类都是从Tobject类派生出来的。
这种方式的缺陷就是:在使用对象上进行操作时必须知道它的数据类型。事实上,Object类型的变量或参数只能应用于由TObject 定义的对象和属性。
例如:(sender as tbutton).caption 做类型转换
to: stanely(俺是邢她汉子)
谢谢你的方法。
回复人: 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;