码迷,mamicode.com
首页 > Windows程序 > 详细

TControl与Windows消息

时间:2016-07-29 21:27:46      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

TControl将系统消息转换成VCL事件,以将系统消息融入VCL中。鼠标的事件就是一个很好的例子,当我们单击鼠标时会产生鼠标的单击消息,而这个单击消息是怎么被处理并执行的呢?

在Control单元中有这样的一段代码:

 1 TControl = class(TComponent)
 2 private
 3     ...
 4     FControlState: TControlState;    //状态    //TControlState = set of (csLButtonDown, csClicked,  .... , );
 5     ...
 6     FOnMouseDown: TMouseEvent;    //用以接受用户的定义的方法。
 7     ...
 8     procedure DoMouseDown(var Message: TWMMouse; Button: TMouseButton; Shift: TShiftState);
 9     ...
10     procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;    //鼠标左键
11     procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;    //鼠标右键
12     procedure WMMButtonDown(var Message: TWMMButtonDown); message WM_MBUTTONDOWN;   //鼠标中间键
13  protected
14     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
15     ...
16     property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
17 end;

TControl声明了一个OnMouseDown属性,该属性读写一个称为FOnMouseDown的事件指针。当我们需要处理一个按钮被按下的情况时,我们便会定义一个按钮按下的方法,并赋值给按钮OnMouseDown属性。此时,FOnMouseDown就会指向这个用户定义的方法。

当我们左键按下鼠标时候,TObject会调用Dispatch()方法会分发WM_LBUTTIONDOWN消息分发,然后进入相应的消息处理函数。如下:

1 procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
2 begin
3   SendCancelMode(Self);
4   inherited;
5   if csCaptureMouse in ControlStyle then MouseCapture := True; 
6   if csClickEvents in ControlStyle then Include(FControlState, csClicked);
7   DoMouseDown(Message, mbLeft, []);
8 end;

如果是单击事件,则在FControlState中添加csClicked。并且跳转到DoMouseDown()方法中。

 1 procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
 2   Shift: TShiftState);
 3 begin
 4   if not (csNoStdEvents in ControlStyle) then
 5     with Message do
 6       if (Width > 32768) or (Height > 32768) then
 7         with CalcCursorPos do
 8           MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)
 9       else
10         MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
11 end;

在DoMouseDown()中进行一些必要的处理工作后,就会调用MouseDown();

1 procedure TControl.MouseDown(Button: TMouseButton;
2   Shift: TShiftState; X, Y: Integer);
3 begin
4   if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
5 end;

在MouseDown()中,就会通过FOnMouseDown事件指针去执行用户定义的代码。此时就完成了从一个WM_LBUTTIONDOWN消息转换成相应的代码过程。

另外,值得注意的是,鼠标的Click事件是没有相应的消息的,鼠标的单击事件被包含在WM_LBUTTIONDOWN消息中,而鼠标的双击事件的消息是WM_LBUTTONDBLCLK消息。而,我们如果要单击鼠标,会先处理OnMouseDown()事件,然后再处理OnClick()事件。并且,如果我们双击鼠标,首先先处理OnMouseDown()事件,然后再处理OnDblClick()事件。这一点很好被验证:

 1 procedure TForm1.FormClick(Sender: TObject);
 2 begin
 3   ShowMessage(click);
 4 end;
 5 
 6 procedure TForm1.FormDblClick(Sender: TObject);
 7 begin
 8   ShowMessage(dblclick);
 9 end;
10 
11 procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
12   Shift: TShiftState; X, Y: Integer);
13 begin
14   ShowMessage(Down);
15 end;

如果我们不注释第14行,那么无论我们如何点击鼠标,都只能处理OnMouseDown()事件,然后ShowMessage()并得到焦点,OnClick()或OnDblCLick事件就不会被执行到。同样,当我们双击鼠标的时候,首先会ShowMessage(‘click‘)。

 

 

TControl与Windows消息

标签:

原文地址:http://www.cnblogs.com/Blogs-young-chan/p/5719642.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!