请教关于Delphi的事件。(90分)

  • 主题发起人 主题发起人 元无天
  • 开始时间 开始时间

元无天

Unregistered / Unconfirmed
GUEST, unregistred user!
我在窗体上放了一个TButton,用到了它的onclick事件,在事件过程中
写了一段实现代码。
我想问各位一个问题。
Delphi到底是如何调用buttonclick(sender)这个过程的呢?当我在单击它的时候,
delphi为什么可以调用到该过程?我没有写出调用的代码啊。
Delphi做了一系列什么工作,以便可以调用该过程?
请详细讲解原理。
另外,在object inspector中,有Events页,单击左边一列的onclick一行,在右边
一列出现'button1click' ,这个buttonclick是事件名,还是过程名?或者是别的什么?


 
buttonclick是过程名.
其实Delphi是响应的Window消息WM_LButtonUp事件,判断一下如果是左键
就调用OnClick指向的过程
 
怎么没有人回符答啊,分不够可以加。
 
你看看 Delphi 带的源码就明白了,
type
TNotifyEvent = Procedure(Sender: TObject) of Object;
...
type
TMyControl = Class(TMyParentClass)
private
FOnClick: TNotifyEvent;
published
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;

...
procedure TMyControl.xxx(xxx);
begin
...
if Assigned(FOnClick) then FOnClick(Self);
...
end;

Understand ???
 
ButtonClick是过程(方法)名
OnClick是方法指针

procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
//响应WM_LBUTTONUP消息并引发OnClick事件
end;
DoMouseUp(Message, mbLeft);
end;

procedure TControl.Click;
begin
{ Call OnClick if assigned and not equal to associated action's OnExecute.
If associated action's OnExecute assigned then call it, otherwise, call
OnClick. }
if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
FOnClick(Self)
else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
ActionLink.Execute(Self)
else if Assigned(FOnClick) then //当方法指针有效时调用方法指针指向的方法(ButtonClick)
FOnClick(Self);
end;
 
to SupermanTm:
能更详细一点吗?
procedure TMyControl.xxx(xxx);
begin
...
if Assigned(FOnClick) then FOnClick(Self);
...
end; 这个过程能详细一点吗? 我是想知道delphi的编译器 ,在调用buttonclick
过程时,加入了一些什么样的代码。应该加入一些代码,可以以伪码讲解吗?
 
TButton是从TButtonControl-TWinControl-TControl一层一层继承下来的,其中TControl中
处理了Windows的WM_LBUTTONUP消息,当鼠标在这个Button上单击并弹起时会传递这个WM_LBUTTONUP
消息给Button,Button收到WM_LBUTTONUP后触发WMLButtonUp消息处理过程,如果这个控件是可单击的
(csClicked in ControlState)并且鼠标位置是在客户区内,就调用Click方法,你看到Click方法中检查
FOnClick这个过程类型的变量是否赋值,其实也就是我们是否写了Button的OnClick事件,如果写了则
通过这个过程类型的变量调用它.

ButtonClick是一个过程名,出现在Events页中就是表示我们在设计的时候就给Button的OnClick事件赋了值,
它的值就是过程ButtonClick(请注意OnClick是过程类型的事件属性,它指向过程类型的成员变量FOnClick),
我们也可以在程序中动态给Button的OnClick事件赋值,而不是在设计时指定:
比如Button.OnClick:=MyButtonClick,只需要定义一个过程MyButtonClick就可.不过这个过程必须是一个对象的成员,
而且它的参数必须是(Sender:TObject);


procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do MouseUp(Button, KeysToShiftState(Keys), XPos, YPos);
end;

procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
end;

procedure TControl.Click;
begin
{ Call OnClick if assigned and not equal to associated action's OnExecute.
If associated action's OnExecute assigned then call it, otherwise, call
OnClick. }
if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
FOnClick(Self)
else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
ActionLink.Execute(Self)
else if Assigned(FOnClick) then
FOnClick(Self);
end;
 
后退
顶部