14.4.2 鼠标消息处理程序
显示CSketcherView类的属性窗口,单击Messages图标,显示这个类可以处理的消息。在视图类的属性窗口中,单击一种鼠标消息的ID,然后在相邻的列中单击下拉箭头,从下拉列表中选择,即可创建鼠标消息的处理程序。例如,尝试对WM_LBUTTONUP消息选择<add> OnLButtonUp。对消息WM_LBUTTONDOWN和WM_MOUSEMOVE消息重复这个过程。在CSketcherView类中生成的函数分别是OnLButtonDown()、OnLButtonUp()和OnMouseMove()。现在不用修改这些函数的名称,因为以后将针对已经在CSketcherView类的基类中定义的函数添加重写函数。下面分析如何实现这些处理程序。
首先观察WM_LBUTTONDOWN消息处理程序。下面是生成的框架代码:
- void CSketcherView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CView::OnLButtonDown(nFlags, point);
- }
可以看到其中有一个对基类处理程序的调用。如果不添加任何代码的话,那么这将确保调用这个基类处理程序。就目前而言,在处理这个消息时,不需要调用这个基类处理程序,尽管可以这么做。是否需要调用消息的基类处理程序要视情况而定。
通常,用于说明添加代码位置的注释具有很好的指导作用。如同目前的这个实例那样,注释建议调用基类处理程序是可选的,在添加自己的消息处理代码时可以忽略它。注释相对于基类消息处理程序调用的位置也很重要,因为有时必须在添加的代码前调用基类消息处理程序,有时则必须在添加的代码后调用基类消息处理程序。注释表明了所添加代码相对于基类消息处理程序调用的位置。
WM_LBUTTONDOWN处理程序的参数有两个:
nFlags是UINT类型,它包含很多状态标志,表明是否按下各种键。UINT类型在Windows API中定义,对应于32位无符号整数。
point是CPoint对象,它定义按下鼠标左键时光标的位置。
nFlags的值可以是下列符号值的任意组合,见表14-5。
表 14-5
|
标 志
|
说 明
|
|
MK_CONTROL
|
按下Ctrl键
|
|
MK_LBUTTON
|
按下鼠标左键
|
|
MK_MBUTTON
|
按下鼠标中间键
|
|
MK_RBUTTON
|
按下鼠标右键
|
|
MK_XBUTTON1
|
按下第一个额外的鼠标键
|
|
MK_XBUTTON2
|
按下第二个额外的鼠标键
|
|
MK_SHIFT
|
按下Shift键
|
如果能够检测是否按下了一个键,就可以根据键的状态,对消息进行不同的处理。nFlags的值可以包含一个以上这些的指示器,每个指示器都对应于这个字中的一个特定位,所以可以使用按位AND运算符测试特定的键。例如,要测试是否按下了Ctrl键,可以编写下列代码:
- if(nFlags & MK_CONTROL)
- // Do something...
-
只有nFlags变量设置了MK_CONTROL位,表达式nFlags & MK_CONTROL的值才是TRUE。这样,在按下鼠标左键时,根据是否也按下了Ctrl键,可以采取不同的动作。由于此处使用的是按位AND运算符,因此对应的位将进行AND运算。不要把这个运算符同逻辑与运算符&&相混淆,它无法完成这里的运算。
传递到其他两种消息处理程序的参数和OnLButtonDown()函数相同,针对它们生成的代码是:
- void CSketcherView::OnLButtonUp(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CView::OnLButtonUp(nFlags, point);
- }
- void CSketcherView::OnMouseMove(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CView::OnMouseMove(nFlags, point);
- }
除了函数名称以外,框架代码都一样。
如果观察一下CSketcherView类定义末尾的代码,那么可以看到添加了3个函数声明:
- // Generated message map functions
- protected:
- DECLARE_MESSAGE_MAP()
- public:
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- };
-
这些声明把添加的函数标识为消息处理程序。在了解了传递到鼠标消息处理程序的信息以后,下面将添加一些代码,使这些处理程序完成特定的工作。