- 浏览: 2058408 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (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 1573摘自:http://topic.csdn.n ... -
TUpdateSQL更新问题 提示Update Failed
2011-08-29 20:26 1238摘自:http://topic.csdn.net/u/200 ... -
图解如何用Eurekalog跟踪程序错误
2011-08-12 07:28 941图解如何用Eurekalog跟踪程序错误 摘自:h ... -
VirtualBox 复制VDI 并能创建新的虚拟机
2011-07-21 11:14 2739摘自:http://www.nonabyte.net/how- ... -
截获所有异常 不报错
2011-07-12 16:52 1239摘自:http://media.ccidnet.c ... -
delphi exe程序以及DLL程序如何在模块内部获得各自的路径
2011-07-11 16:38 1305delphi Exe程序以及DLL程序如何在模块内部获得各自的 ... -
Delphi文本文件读写
2011-07-11 14:55 1244Delphi文本文件读写 (2008-10-31 1 ... -
Delphi自定义的消息的使用
2011-05-31 14:12 2315阅:已验证,可通过; 摘自:http://blog.1 ... -
怎么查看OutputDebugString输出的信息?debugview
2011-05-25 16:02 3835网上很多说用debugview查看,我自己写了一个程序,里面用 ... -
Delphi里查看该变量的内存值
2011-05-25 13:32 1122Delphi里查看该变量的内存值:Run==>Evalu ... -
注册表操作 写入autorun启动项,键值为本程序的全路径
2011-05-20 15:40 1825procedure TForm4.Button2Click ... -
报说包frx7和frxdb7都包含了某个单元的错误
2011-05-11 09:59 10221. 问题描述:在安装FastReport3的时候,安装到- ... -
Delphi中使用ListView和TreeView的Item中的Data可能被忽略的内存泄漏
2011-05-03 14:34 1462摘自:http://blog.csdn.net/g ... -
WM_USER的说明 用户消息ID
2011-04-28 10:46 1687WM_USER 摘自:http://baike.bai ... -
ToolButton不能改变大小
2011-04-28 10:38 3462问题描述:ToolButton不能改变大小? 问 ... -
Delphi里TOOLBAR 上的button的caption为什么显示不出来啊
2011-04-20 17:55 1767Delphi里TOOLBAR 上的button的caption ... -
delphi指针简单入门
2011-04-11 21:42 1156摘自:http://topic.csdn.net/t/2003 ... -
Delphi中paramstr的用法 应用程序间传递数据
2011-04-01 14:33 2104Delphi中paramstr的用法 应用程序间传递数据 ... -
Delphi中的THashedStringList对象 --大数据量时
2011-04-01 13:54 5147Delphi中的THashedStringLi ... -
inherited Create(AOwner); 和直接写inherited有区别吗
2011-03-26 15:44 1323摘自:http://zhidao.baidu.com/que ...
相关推荐
Unity 项目中委托Delegate的用法,项目案例。 Chinar用简单的案例,帮您理解委托的基本用法,注册事件机制问题
### UIAlertView的基本用法 创建一个UIAlertView实例首先需要导入`UIKit`框架: ```swift import UIKit ``` 然后,你可以通过初始化方法来创建一个UIAlertView对象: ```swift let alert = UIAlertView(title: ...
通常,我们会选择`flash.events.Event`或`mx.events.FlexEvent`作为基类,前者适用于基本事件,后者则为Flex框架提供了一些额外的属性和方法。 - 自定义事件类应包含一个构造函数,用于初始化事件的属性。例如,...
《使用Cropper实现图形剪切的基本方法》 在网页开发中,图像处理是一项常见的需求,尤其是在用户上传照片或需要自定义裁剪图片时。Cropper是一款强大的JavaScript图像裁剪库,它提供了丰富的功能和易用的API,使得...
在本主题中,我们将深入探讨JavaScript的基本语法、事件处理以及window对象。 首先,我们来了解一下JavaScript的基本语法。JavaScript语法与C++和Java有相似之处,但更宽松,它允许在一行内编写多条语句。变量声明...
这个“ButterKnife 控件事件基本实现demo”是一个很好的学习资源,可以帮助开发者理解并掌握ButterKnife的基本用法。 ButterKnife的核心功能包括View注入和事件注入: 1. **View注入**:传统方式中,我们需要在...
Java Swing是Java GUI(图形...综上所述,Java Swing的基本用法涵盖了组件的使用、布局管理、事件处理等多个方面,是构建Java桌面应用不可或缺的技能。通过学习和实践,开发者能够创建出功能丰富、用户友好的图形界面。
通过上述介绍,我们可以了解到 `TServerSocket` 和 `TClientSocket` 在 Delphi 中的使用方法及其基本原理。这两种组件能够帮助开发者快速构建出基于 Socket 协议的应用程序,实现客户端与服务器之间的数据交互。在...
C#基本控件用法(winform) C#中的控件用法是非常重要的,尤其是在winform应用程序中。今天,我们将来学习一些基本的控件用法,包括Button、CheckBox、ComboBox、DataGridView、ListView、TreeView和MdiForm等。 ...
前面的文章Android开发教程之Fragment定义、创建与使用方法详细讲述了Fragment的基本概念与用法。这里再来分析一下Fragment监听返回键事件的具体应用。 背景 项目要求用户注册成功后进入修改个人资料的页面,且不...
在Android开发过程中,基本空间的用法是构建用户界面(UI)的基础,这对于任何应用程序都是至关重要的。在“第二天android项目 基本空间的用法”中,我们将会探讨如何有效地利用各种UI元素,如按钮(Button)和菜单...
在实际项目中,用户控件的属性、方法、事件和委托的合理使用,可以极大地提高代码的复用性和可维护性。通过创建用户控件,开发者可以构建出复杂而定制化的界面元素,同时保持代码的清晰和结构化。在设计用户控件时,...
Android ListView 控件基本用法 Android ListView 控件是一种基础控件,主要用于展示列表数据。在 Android 开发中,ListView 控件是最常用的控件之一。下面我们将详细介绍 Android ListView 控件的基本用法。 一、...
下面将详细介绍Delphi中ListView的基本用法。 1. **ListView组件的基本结构** - **Items**: 这是ListView的主要数据存储,每个Item代表列表中的一行。每个Item可以有多个SubItems,用于显示不同的列数据。 - **...
MATLAB GUI的基本用法视频教程涵盖了创建GUI、设计界面元素、处理用户事件等多个方面,对于初学者或希望提高MATLAB GUI编程技能的人来说是极有价值的资源。 在MATLAB GUI中,你可以通过 GUIDE(Graphical User ...
在这个"诚诚照片Demo"中,我们将探讨DrawGrid控件的基本用法,通过实例来学习如何在C++ Builder中有效地使用它。 首先,要在C++ Builder项目中添加DrawGrid控件,你需要打开工具箱,并将DrawGrid控件拖放到窗体上。...
同时,可以使用`UITableViewDelegate`的`didSelectRowAt`方法来监听选中事件。 其次,自定义Style多选通常涉及到自定义单元格。`UITableViewCellStyle`提供了多种预设样式,但有时我们可能需要自定义单元格以满足...
总结来说,Leaflet是一个强大的开源地图库,它的基本用法包括初始化地图、加载底图、添加标记和信息弹窗、图层控制以及事件监听。而Cesium则提供了3D地图功能,两者结合可以构建出更丰富的Web地图应用。在实际开发中...
本文将深入探讨`onclick`事件的工作原理、使用方法以及几个实用示例。 `onclick`事件是一个内联事件处理器,它可以绑定到任何可点击的HTML元素,如按钮、链接或图像等。当用户在浏览器中对这些元素进行点击操作时,...
本教程将通过一系列小例子来讲解 jQuery 的基本用法,包括事件处理、DOM 操作、选择器、动画效果等核心概念。** ### 1. **选择器** jQuery 提供了丰富的选择器,使得选取 HTML 元素变得非常简单。例如: - `$("#id...