在视中接收鼠标输入:
鼠标消息是我们常需要处理的消息,消息分为:鼠标移动,按钮按下/松开,双击。利用ClassWizard可以轻松的添加这几种消息映射,下面分别讲解每种消息的处理。
WM_MOUSEMOVE对应的函数为OnMouseMove( UINT nFlags, CPoint point ),nFlags表明了当前一些按键的消息,你可以通过“位与”操作进行检测。
- MK_CONTROL Ctrl键是否被按下 Set if the CTRL
key is down.
- MK_LBUTTON 鼠标左键是否被按下 Set if the left
mouse button is down.
- MK_MBUTTON 鼠标中间键是否被按下 Set if the middle
mouse button is down.
- MK_RBUTTON 鼠标右键是否被按下 Set if the right
mouse button is down.
- MK_SHIFT Shift键是否被按下 Set if the SHIFT
key is down.
point表示当前鼠标的设备坐标,坐标原点对应视左上角。
WM_LBUTTONDOWN/WM_RBUTTONDOWN(鼠标左/右键按下)对应的函数为OnLButtonDown/OnRButtonDown(
UINT nFlags, CPoint point )参数意义和OnMouseMove相同。
WM_LBUTTONUP/WM_RBUTTONUP(鼠标左/右键松开)对应的函数为OnLButtonUp/OnRButtonUp(
UINT nFlags, CPoint point )参数意义和OnMouseMove相同。
WM_LBUTTONDBLCLK/WM_RBUTTONDBLCLK(鼠标左/右键双击)对应的函数为OnLButtonDblClk/OnRButtonDblClk(
UINT nFlags, CPoint point )参数意义和OnMouseMove相同。
下面我用一段伪代码来讲解一下这些消息的用法:
代码的作用是用鼠标拉出一个矩形
global BOOL fDowned;//是否在拉动
global CPoint ptDown;//按下位置
global CPoint ptUp;//松开位置
OnLButtonDown(UINT nFlags, CPoint point)
{
fDowned=TRUE;
ptUp=ptDown=point;
DrawRect();
...
}
OnMouseMove(UINT nFlags, CPoint point)
{
if(fDowned)
{
DrawRect();//恢复上次所画的矩形
ptUp=point;
DrawRect();//画新矩形
}
}
OnLButtonUp(UINT nFlags, CPoint point)
{
if(fDowned)
{
DrawRect();//恢复上次所画的矩形
ptUp=point;
DrawRect();//画新矩形
fDowned=FALSE;
}
}
DrawRect()
{//以反色屏幕的方法画出ptDown,ptUp标记的矩形
CClientDC dc(this);
MakeRect(ptDown,ptUp);
SetROP(NOT);
Rect();
}
坐标间转换:在以上的函数中point参数对应的都是窗口的设备坐标,我们应该将设备坐标和逻辑坐标相区别,在图32_g1由于窗口使用了滚动条,所以传入的设备坐标是对应于当前窗口左上角的坐标,没有考虑是否滚动,而逻辑坐标必须考虑滚动后对应的坐标,所以我以黄线虚拟的表达一个逻辑坐标的区域。可以看得出同一点在滚动后的坐标值是不同的,这一规则同样适用于改变了映射方式的窗口,假设你将映射方式设置为每点为0.01毫米,那么设备坐标所对应的逻辑坐标也需要重新计算。进行这种转换需要写一段代码,所幸的是系统提供了进行转换的功能DC的DPtoLP,LPtoDP,下面给出代码完成由设备坐标到逻辑坐标的转换。
图32_g1
CPoint CYourView::FromDP(CPoint point)
{
CClientDC dc(this);
CPoint ptRet=point;
dc.PrepareDC();//必须先准备DC,这在使用滚动时让DC重新计算坐标
//如果你作图设置了不同的映射方式,则在下面需要设置
dc.SetMapMode(...)
//
dc.DPtoLP(&ptRet);//DP->LP进行转换
return ptRet;
}
在图32_g1中以蓝线标记的是屏幕区域,红线标记的客户区域。利用ScreenToClient,ClientToScreen可以将坐标在这两个区域间转换。
在视中接收键盘输入:
键盘消息有三个:键盘被按下/松开,输入字符。其中输入字符相当于直接得到用户输入的字符这在不需要处理按键细节时使用,而键盘被按下/松开在按键状态改变时发送。
WM_CHAR对应的函数为OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ),其中nChar为被按下的字符,nRepCnt表明在长时间为松开时相当于的按键次数,nFlags中的不同位代表不同的含义,在这里一般不使用。
WM_KEYDOWN/WM_KEYUP所对应的函数为OnKeyDown/OnKeyUp( UINT nChar, UINT nRepCnt,
UINT nFlags )nChar代表按键的虚拟码值,如VK_ALT为ALT键,VK_CONTROL为Ctrl键。nFlags各位的含义如下:
Value |
Description |
07 |
Scan code (OEM-dependent
value). |
8 |
Extended key, such as a function
key or a key on the numeric keypad (1 if it is an extended key). |
910 |
Not used. |
1112 |
Used internally by Windows. |
13 |
Context code (1 if the ALT
key is held down while the key is pressed; otherwise 0). |
14 |
Previous key state (1 if the
key is down before the call, 0 if the key is up). |
15 |
Transition state (1 if the
key is being released, 0 if the key is being pressed). |
《Visual C++开发指南》
闻怡洋/文