OnClick事件是在哪被调用的?(300分)

  • 主题发起人 主题发起人 风卷残月
  • 开始时间 开始时间

风卷残月

Unregistered / Unconfirmed
GUEST, unregistred user!
其实问题在群里面问过,昨天忽发奇想,用鼠标点击控件的事件顺序是
OnMouseDown --> OnClick --> OnMouseUp
因为最近接触了一些VCL,对Windows消息挺感兴趣, 可只知道鼠标按下与弹起消息,OnClick可没听过什么消息,后来问群里的朋友才知道是BN_CLICKED,控件消息,不是窗体消息,郁闷了.以前曾接触过一些串口通信的控件,其中有一事件为串口有数据传来,看代码才知道原来是用一定时器不斷读串口,一發現有數據就调用那个事件过程. 所以感觉,事件也是过程,只是在控件里面是被调用而已,一切智能的东西都被封装起来了.同理,事件只是VCL中的过程,那些控件里面在哪里捕获到bn_Clicked个消息然后调用 OnClick呢? 曾在TButton找到部分:

procedure TButton.CNCommand(var Message: TWMCommand);
begin
if Message.NotifyCode = BN_CLICKED then Click;
end;

也就是说收到BN_CLICKED消息就执行Click,这与自己当初的想法一样, 可后来又做一测试,从TWinControl继承一组件,然后开放他的OnClick : property OnClick; 测试了一下,组件可以响应这个消息,所以就说明TWinControl(或者TContrl)就已经响应了Click,他是如何响应的呢? 自己昨晚瞎找了一晚上都搞不定, 麻烦知道的大虾告诉下,在此拜谢.
(注:这贴 感谢以前告诉BN_CLICK的朋友,同时也感谢帮搞定TWinControl.Click的强人们:)

说简单一点就是Click是在何时被谁调用的,找出代码就OK! 先谢过了
 
注意control.pas单元的代码:
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;
回调函数完成具体事件,Click详细代码:
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;
所以button的Click事件总是在鼠标弹起是被触发
够清楚了吧,所有自定义的过程都要通过windows消息被激发时调用
 
呵呵,谢谢楼上的,刚好群里的朋友也给出了答案,为了求解偶做了个测试:
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
在Click之前加了句MessageBox,可不显示,原因是我点击的是窗体,并没有执行TControl.Click,去执行TForm.Click去了. 现在在找Form的代码,相信他和TButton一样里面有东西拦截.
 
残月,
我是小艳,我来接分的啦!哈哈!
 
顶,再顶
 
在TCustomForm中找不到Click相?的代?,所以就把目光放到
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then
这句上,上面的问题已经解决,结贴先,感谢帮助过的各位朋友[:D]
 
多人接受答案了。
 
后退
顶部