学习时,关于OnClick,OnKeyDown事件中参数的疑问.(200分)

  • 主题发起人 主题发起人 sqlserver2
  • 开始时间 开始时间
S

sqlserver2

Unregistered / Unconfirmed
GUEST, unregistred user!
对于一些控件的Event的类型;
eg:
OnClick:
打开delphi的代码,可以找到
type TNotifyEvent = procedure (Sender: TObject) of object;
所以我们可以自定义一个TNotifyEvent类型的方法;
procedure MyClick(Sender: TObject);

然后就可以如下赋值
Button1.OnClick := MyClick;

但是我不明白,上面的定义中,Sender为什么就可以传触发此Click事件的对象

又如:OnKeyDown中,
type
TKeyEvent = procedure (Sender: TObject; var Key: Word; Shift: TShiftState) of object;
这里Key为什么就可以传键值了;


关于这方面的知识,请各位能高知一二;
这些东东写在Vcl的什么地方了?
 
写在控件的内部了,您再仔细分析源码你就知道是怎么回事了!
全部都是有很明确简单的代码实现的.
 
cancheung:

哈哈,就是找不到在控件的什么地方实现的啊.

能不能举个例子告知我写在哪了?
 
其实就是指向事件调用者的事件指针,所以在调用的时候会引用调用该过程或方法的对象的指针所指向的对象,自然就是调用者对象了。
呵呵:)我说的好像绕口令,不知道楼主明白了没有...
 
Johnny_du:

我觉得你这样说是解释了OnClick,OnKeyDown中的Sender是指向调用者对象;

但我还是不明白在我列出的代码中,Sender是怎样指向该对象,
OnKeyDown中的Key又是怎样指向键盘键值的?
又例如:
TTreeView的OnChange事件
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
end;
这里的Node是怎样找到树节点的啊?
 
是这样。你说的这些问题就关系到Win32底层编程部分有关消息系统、还有屏幕坐标系统等问题了。笼统的说就是当你在屏幕上用鼠标单击(或双击)了某个位置,或者敲了一下键盘后,Windows消息系统就会发出相应的消息;然后Windows就会查看当前哪个进程的哪个可视化控件处于活动状态并查看鼠标(或光标)位置,然后查找相应事件指针,若指针为null则返回(没有编写相应事件响应代码),若有则转向该事件处理过程入口并将该消息以及屏幕视口坐标位置等参数传递给该过程,当过程处理完毕后,返回Windows从而进入下一消息循环。
 
楼上:

你所说有关消息循环方面的知识我大概能理解,也看到Vcl里处理消息的一些代码

TCustomForm及直到TControl父类的WndProc(var Message: TMessage);方法,都是处理消息的;
这说到消息与事件是怎关联的;

这是关心的问题有点不对啊.
可能是说得不够清楚吧,
比如说:
如果想在TListBox的一个子类中加入一个新事件,在这个新事件参数中要求有一个是对应TListBox当前所选的行的索引Index;
即MyEvent(Sender: TObject; Index: Integer);//这个Index就是当前所选的行
该是怎去写这个新事件,让Index达到要求呢?

Delphi的工程师是怎去定义一个控件的事件?
 
1、oncick:=MyClick 不是因为sender触发了myclick,Onclick就像Caption一样,可以被赋值的,其实Onclick就是一个属性。之所以被触发,是因为控件接到windows传来的单击事件后处理的
if Assigned(FOnClick) then FOnClick(Self) //就是如果Onclick 有赋值就运行Oncick的意思。

2、key的参数前面用Var 来申明,说明这个参数按地址传输的,
普通的情况下参数都是重新拷贝到另一个内存块。
具体区别看帮助吧,都很详细了。
 
还是不明白
 
推荐李维的那本<Inside VCL>,看完后就明白了.
 
是啊,多看一下那些,写控件的书本就行了,关于DELPHI中的书,几乎每一本都多多少少地提到,至于代码问题就要看你的悟性了,呵呵
 
多看一下那些,写控件的书本就行了

这个比较实际可行
 
//你安装一下这个控件看看

unit mycontrol;

interface

uses
Windows, Messages, SysUtils, Classes, Controls;
type
TMyEnvent=procedure(var NewValue:integer;var AllowChanged:Boolean) of object;
//这些变量前面用var 来申明
TMycontrol = class(TWinControl)
//整个控件的作用就是你给控件的MyValue赋值,就会触发OnValueChange事件,提示是否允许修改,以及修改成什么值。
private
FMyValue: Integer;
FOnValueChange: TMyEnvent;
procedure SetMyValue(const Value: Integer);
//这个变量用const 来申明,有什么区别自己看帮助
protected
public
published
property MyValue:Integer read FMyValue write SetMyValue;
property OnValueChange:TMyEnvent read FOnValueChange write FOnValueChange;
//这个就是传说中的事件了,怎么触发的看下面解释
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [tmycontrol]);//控件会被安装在Standard下。
end;

procedure tmycontrol.SetMyValue(const Value: Integer);
var
iNewValue:integer;
bAllChange:Boolean;
begin
iNewValue:=Value;
bAllChange:=true;
if Assigned(fOnValueChange) then FOnValueChange(iNewValue,bAllChange);
//这行代码就是触发传说中的事件的,你在OnValueChange事件里面写代码就知道了
// if Assigned(fOnValueChange) then FOnValueChange([blue]Value[/blue],bAllChange);
//这行是错误的,就是因为Value是用Const申明的,相当于常数
if bAllChange then //这个bAllchange的值会可以OnValueChange中被修改。
begin
FMyValue := iNewValue;//这个iNewValue的值也会可以OnValueChange中被修改。
end;
end;

end.
 
谢谢楼上各位,特别是Tell_me_why提供了例子
 
多人接受答案了。
 
if Assigned(fOnValueChange) then FOnValueChange(iNewValue,bAllChange);
这一句怎么理解?
 
如果给fOnValueChange分配了内存,就执行它啊.
 

Similar threads

S
回复
0
查看
738
SUNSTONE的Delphi笔记
S
S
回复
0
查看
730
SUNSTONE的Delphi笔记
S
后退
顶部