- 浏览: 2015008 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
事件的基本用法
事件的基本用法
我在对RO例子 Variants 跟踪时有了个意外收获,有种茅塞顿开。
提起事件,我也用过,一般都是控件上提供啥事件我就用啥了。
用的最多的就是OnClick事件,至于为啥这样用,我不知道,
稀里湖途地我用了快小半辈子了。
我从下面的代码开始跟踪的:
procedure TVariantsClientMainForm.FormCreate(Sender: TObject);
var
i: integer;
begin
for i := 0 to ComponentCount - 1 do
if (Components[i] is TROMessage) then begin
rgMessageType.Items.AddObject(TROMessage(Components[i]).Name, Components[i]);
end;
rgMessageType.ItemIndex := 1;
FVariantsService := (RORemoteService as IVariantsService);
end;
在 rgMessageType.Items.AddObject(TROMessage(Components[i]).Name, Components[i]);上
下了一个断点,单步跟踪,当我跟踪到下面代码时:
procedure TStringList.Changed;
begin
if (FUpdateCount = 0) and Assigned(FOnChange) then
FOnChange(Self);
end;
当执行FOnChange(Self);时程序无形中地跳到了下面代码的位置:
procedure TCustomRadioGroup.ItemsChange(Sender: TObject);
begin
if not FReading then
begin
if FItemIndex >= FItems.Count then FItemIndex := FItems.Count - 1;
UpdateButtons;
end;
end;
呀!这咋这么奇怪呢?TStringList.Changed 一执行程序就会跳到TCustomRadioGroup.ItemsChange这来
这是为啥呢?在这里我郁闷了很久。啥东西的作用始得可以在两个类之间方法的跳来跳去的呢?
于是,我试图往深里跟踪FOnChange(Self);它想到里面看看是咋回事,可是单步不进去呀,一个单之后
就直接跳到TCustomRadioGroup.ItemsChange这里了。我反复地跟踪,很是郁闷,这是为啥呢?
从语法上分析一下FOnChange(Self);
FOnChange: TNotifyEvent;
FOnChange 定义的是一个事件。
TNotifyEvent = procedure(Sender: TObject) of object;
啥意思?定义成这样的事件就可以类之间的方法跳来跳去的吗?
它咋知道从TStringList跳到TCustomRadioGroup呢?它咋不往别的类上跳去呢?
我估计肯定是有啥说法,不可能是瞎乱跳的吧。
我更郁闷了,我垂头又丧气,这是为啥呢?
我突然想起了Items定义的是 TString而当执行rgMessageType.Items.AddObject
AddObject执行的确是TStringlist下的AddObject,因为在TCustomRadioGroup.create中
FItems是这样创建的:FItems := TStringList.Create;
我合计肯定是得有事件赋值了.
我打开TCustomRadioGroup.create下一看还真是这样:
TStringList(FItems).OnChange := ItemsChange;
我明白了事件为啥会跳来跳去的了,原来桥是在这搭起来的.
整体看一下TStringList类
TStringList = class(TStrings)
private
...
FOnChange: TNotifyEvent;
..FOnChanging: TNotifyEvent;.
protected
procedure Changed; virtual;
procedure Changing; virtual;
...
public
...
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
事件就是这么用,可能就是上面的这样的结构用法.有如下特点:
1、事件看上去就是一个属性,所以在类中添加事件的方法与添加属性是一样的。
如:property OnChange: TNotifyEvent read FOnChange write FOnChange;
2、添加事件需要定义属性与之相关的域,该域用于存储事件引用的实际方法指针。
如:FOnChange: TNotifyEvent;
FOnChange 域为方法指针,在读取OnChange属性时将调用该指针指向的方法;
而给OnChange属性赋值时,所赋的值(方法地址)将写到FOnChange域中,由它保存
方法的入口地址
如,在TCustomRadioGroup.create中有如下语句:
TStringList(FItems).OnChange := ItemsChange;
经过这样的赋值之后FOnChange域保存的ItemsChange方法的入口地址。
也就是说TCustomRadioGroup下的ItemsChange方法的指针。也就是说该方法的首地址。
所以执行FOnChange(Self);它实际上就是执行ItemsChange方法了。
3、还需要声明一个响应数据域变化的方法
如:procedure Changed; virtual;
procedure Changing; virtual;
看看它是怎么实现的:
procedure TStringList.Changed;
begin
if (FUpdateCount = 0) and Assigned(FOnChange) then
FOnChange(Self);
end;
数据域在变化前的事件。
procedure TStringList.Changing;
begin
if (FUpdateCount = 0) and Assigned(FOnChanging) then
FOnChanging(Self);
end;
Assigned 方法判断FOnChange域是否已经赋值了,也就是说是否指定了某个方法,
如果没有指定,则其值为nil,否则程序通过FOnChange方法指针域调用具体的方法。
跟据VCL的惯例,有人把这叫夹心面包,皮萨饼,确实在VCL中能看到很多这样的手法。
看看下面的代表,Changing;和Changed;中间夹着一些代码。
procedure TStringList.InsertItem(Index: Integer; const S: string; AObject: TObject);
begin
Changing;
if FCount = FCapacity then Grow;
if Index < FCount then
System.Move(FList^[Index], FList^[Index + 1],
(FCount - Index) * SizeOf(TStringItem));
with FList^[Index] do
begin
Pointer(FString) := nil;
FObject := AObject;
FString := S;
end;
Inc(FCount);
Changed;
end;
变化前变化后所要触发的事件。
不知道这是不是事通的一般通常的用法,可能是,原来事件是这么个用法。
TStringList(FItems).OnChange := ItemsChange;
结过这么一赋值之后
FOnChanging(Self); 就相当于执行:
相当于调用 TCustomRadioGroup类下的ItemsChange 方法
说明某个类的方法指针域可以具有指向其他类的方法的值
属于方法指针类型,用于处理事件。
发表评论
-
form打开时的关闭代码
2011-10-25 20:29 1532摘自:http://topic.csdn.n ... -
TUpdateSQL更新问题 提示Update Failed
2011-08-29 20:26 1208摘自:http://topic.csdn.net/u/200 ... -
图解如何用Eurekalog跟踪程序错误
2011-08-12 07:28 912图解如何用Eurekalog跟踪程序错误 摘自:h ... -
VirtualBox 复制VDI 并能创建新的虚拟机
2011-07-21 11:14 2699摘自:http://www.nonabyte.net/how- ... -
截获所有异常 不报错
2011-07-12 16:52 1206摘自:http://media.ccidnet.c ... -
delphi exe程序以及DLL程序如何在模块内部获得各自的路径
2011-07-11 16:38 1276delphi Exe程序以及DLL程序如何在模块内部获得各自的 ... -
Delphi文本文件读写
2011-07-11 14:55 1188Delphi文本文件读写 (2008-10-31 1 ... -
Delphi自定义的消息的使用
2011-05-31 14:12 2277阅:已验证,可通过; 摘自:http://blog.1 ... -
怎么查看OutputDebugString输出的信息?debugview
2011-05-25 16:02 3805网上很多说用debugview查看,我自己写了一个程序,里面用 ... -
Delphi里查看该变量的内存值
2011-05-25 13:32 1098Delphi里查看该变量的内存值:Run==>Evalu ... -
注册表操作 写入autorun启动项,键值为本程序的全路径
2011-05-20 15:40 1790procedure TForm4.Button2Click ... -
报说包frx7和frxdb7都包含了某个单元的错误
2011-05-11 09:59 9851. 问题描述:在安装FastReport3的时候,安装到- ... -
Delphi中使用ListView和TreeView的Item中的Data可能被忽略的内存泄漏
2011-05-03 14:34 1434摘自:http://blog.csdn.net/g ... -
WM_USER的说明 用户消息ID
2011-04-28 10:46 1651WM_USER 摘自:http://baike.bai ... -
ToolButton不能改变大小
2011-04-28 10:38 3438问题描述:ToolButton不能改变大小? 问 ... -
Delphi里TOOLBAR 上的button的caption为什么显示不出来啊
2011-04-20 17:55 1717Delphi里TOOLBAR 上的button的caption ... -
delphi指针简单入门
2011-04-11 21:42 1123摘自:http://topic.csdn.net/t/2003 ... -
Delphi中paramstr的用法 应用程序间传递数据
2011-04-01 14:33 2054Delphi中paramstr的用法 应用程序间传递数据 ... -
Delphi中的THashedStringList对象 --大数据量时
2011-04-01 13:54 5105Delphi中的THashedStringLi ... -
inherited Create(AOwner); 和直接写inherited有区别吗
2011-03-26 15:44 1292摘自:http://zhidao.baidu.com/que ...
相关推荐
Unity 项目中委托Delegate的用法,项目案例。 Chinar用简单的案例,帮您理解委托的基本用法,注册事件机制问题
UIAlertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法
关于用户控件的一些基本用法,包括:属性、方法、委托及事件
JavaScript的基本语法 事件处理 window对象
前面的文章Android开发教程之Fragment定义、创建与使用方法详细讲述了Fragment的基本概念与用法。这里再来分析一下Fragment监听返回键事件的具体应用。 背景 项目要求用户注册成功后进入修改个人资料的页面,且不...
jquery 各种基本用法小例子,包括事件,动作,各种选择
本工程实现了QT中event事件基本用法,提供完整项目实例代码,下载即可使用
主要介绍了C#基本打印事件用法,实例分析了C#中print打印及DrawString文本字符串绘制等相关技巧,需要的朋友可以参考下
Android RecyclerView的基本用法Demo(源码),包含头视图的添加,数据展示,子项分割线引入及样式设置,子项的增删及动画,子项长短按事件引入等
基本的地图创建以及事件,图表类型等综合在一起的小文档
Android RecyclerView的基本用法Demo(源码),包含数据展示,子项分割线引入及样式设置,子项的增删及动画,子项长短按事件引入等
(1) 掌握JDK1.1的事件处理机制。 (2) 掌握处理各种鼠标与键盘事件的编程方法。 (3) 熟悉事件适配器的使用方法。
微地震事件初至的精确拾取是微震时空定位的关键技术之一。简述了STA/LTA(Short–Term to Long–...因此,采用STA/LTA识别微地震事件,初步确定初至范围,然后再使用AIC方法精确拾取初至,是微地震事件初至拾取的较好方法。
主要介绍了详解vue中v-on事件监听指令的基本用法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
方法一:在标签上加入 onLoad=”” onResize=”” 方法 写上对应的方法即可方法二:[removed]=function(){///…..} 在方法里面写上对应的代码即可着两种方法基本都可以解决你的问题了 代码如下: [removed]=...
在大型强子对撞机上使用ATLAS检测器,根据在质心能量为7 TeV时收集的37pb-1质子-质子碰撞数据,对QCD喷射事件中的基础事件敏感的分布进行了测量。 在每种情况下,均在垂直于最硬射流的方位角区域中测量了带电粒子的...
TListView组件使用方法 引用CommCtrl单元 procedure TForm1.Button1Click(Sender: TObject); begin ListView_DeleteColumn(MyListView.Handle, i);//i是要删除的列的序号,从0开始 end; 用LISTVIEW...
网络请求(带参数),解析响应json,RecyclerView列表,RecyclerAdapter,列表点击事件
获取对象属性事件和方法本人看了很多网上有关的源码,基本上都是一样的,不过功能就不是很强大 有感与此,本人特写了一个功能强大点的欢迎大家使用