1: 修改方法一
重载CView里的OnMouseMove函数 .
重载方法 :
“View” -> “ClassWizard” (Ctrl + W) -> 右侧Messages栏选择”WM_MOUSEMOVE” , 然后点”Add Function” , 点”OK” .
添加代码 :
在 CDocTestView::OnMouseMove()里添加如下代码:
HCURSOR hCur = LoadCursor( NULL , IDC_CROSS ) ;
::SetCursor(hCur);
机制分析:
系统默认每次调用OnMouseMove函数 ,都会重新用程序默认自带的光标来重新绘制光标,所以 ,需要在OnMouseMove里来进行光标的修改才有效 。
2: 修改方法二
重载CView里的OnSetCursor函数 .
重载方法:
“View” -> “ClassWizard” (Ctrl + W) -> 右侧Messages栏选择”WM_SETCURSOR” , 然后点”Add Function” , 点”OK” .
添加代码 :
修改OnSetCursor 为如下代码:
BOOL CDocTestView:: OnSetCursor ()
{
HCURSOR hCur = LoadCursor( NULL , IDC_CROSS ) ;
::SetCursor(hCur);
return TRUE;
}
机制分析:
系统在设置光标时 ,会发送一个WM_SETCURSOR消息 ,此消息会触发OnSetCursor函数 , 所以 ,可以在这个函数里添加修改光标的代码 。
3:修改方法三
重载CView里的PreCreateWindow函数.
重载方法 :
“View” -> “ClassWizard” (Ctrl + W) -> 右侧Messages栏选择” PreCreateWindow” , 然后点”Add Function” , 点”OK” .
添加代码 :
在CDocTestView::PreCreateWindow函数里添加如下代码:
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
LoadCursor( NULL , IDC_CROSS ) ,
(HBRUSH) (COLOR_WINDOW + 1));
机制分析:
缺省窗口创建时, 会以一个结构体WNDCLASS来描述窗体的属性 ,并利用注册机制 ,将此窗口属性注册到系统中,利用AfxRegisterWndClass可以改变窗体本身的属性 ,并对它重新注册 。
4:修改方法四
任意函数中修改鼠标形状
理论上利用SetCursor(…)函数 , 应该可以在任何时候,任何地方修改鼠标形状 ,但实际情况却并非如此 , 每次调用OnMouseMove时候(即每次鼠标移动时) , 系统会调用程序默认原来的一个光标来重新绘制鼠标形状 . 所以, 你如果在其它地方修改光标 , 你会发现这根本不起作用 , 因为每次鼠标一移动 , 它又恢复到原来的形状了 . 这里需要用到另一个API来实现这个功能
SetClassLong() . . .
你可以在任何地方调用下面的代码来修改光标形状:
SetClassLong(this->GetSafeHwnd(),
GCL_HCURSOR ,
(LONG)LoadCursor(NULL , IDC_CROSS));
综合比较:
方法三更加适合于一次性的将默认光标统一替换另一种,并不适合于多次频繁替换。
方法一 ,方法二,可以实现光标的多次变换 ,但是都需要在函数中添加额外的变量来控制显示为不同的光标 。
方法四是最灵活的一种方式,可以在任何时候 ,任何函数里更换鼠标形状 。
附 录
1: LoadStandardCursor使用方法 .
LoadStandardCursor用来载入系统自带的光标 , 调用方式如下:
HCURSOR hCursor = (HCURSOR)AfxGetApp()->LoadStandardCursor(IDC_CROSS);
::SetCursor(hCursor);
2: LoadCursor 使用方法
HCURSOR LoadCursor(HINSTANCE hInstance , // handle to application instance
LPCTSTR lpCursorName); // name or resource identifier
lpCursorName指的是光标的名字 .
hInstance描述的是含有光标的模块句柄 . 这个模块可以是一个可执行文件 , 也可以为空 . 当模块句柄指向一个文件时 , LoadCursor则从这个文件中获取光标 . 当模块句柄为空时 , LoadCursor则从系统中获取光标 .
所以如果你想载入系统自带的光标 , 可以用下面的代码:
HCURSOR hCur = LoadCursor( NULL , IDC_CROSS ) ;
::SetCursor(hCur);
如果想载入资源中自己绘制的光标 , 可以用下面的代码:
HCURSOR hCur = LoadCursor(AfxGetInstanceHandle() ,
MAKEINTRESOURCE(IDC_CURSOR1));
::SetCursor(hCur);
1.显示区域鼠标消息: 1)当鼠标移过窗口的显示区域时, WM_MOUSEMOVE消息 2)WM_LBUTTONDOWN|WM_LBUTTONUP|WM_LBUTTONDBLCLK WM_MBUTTONDOWN|WM_MBUTTONUP|WM_MBUTTONDBLCLK WM_RBUTTONDOWN|WM_RBUTTONUP|WM_RBUTTONDBLCLK (L为左键 M为中键 R为右键) wParam为鼠标按键以及Shift和Ctrl键的状态 lParam为鼠标的显示区域x坐标+y坐标 2.非显示区域鼠标消息 1)WM_NCMOUSEMOVE 2)WM_NCLBUTTONDOWN|WM_NCLBUTTONUP|WM_NCLBUTTONDBLCLK WM_NCLMUTTONDOWN|WM_NCMBUTTONUP|WM_NCMBUTTONDBLCLK WM_NCRBUTTONDOWN|WM_NCRBUTTONUP|WM_NCRBUTTONDBLCLK (NC表示为非显示区域,L为左键 M为中键 R为右键) wParam命中的区域 lParam鼠标的屏幕坐标系x坐标+y坐标 显示区域鼠标消息和显示区域鼠标消息wParam 的位屏蔽有: MK_LBUTTON按下左键 MK_MBUTTON按下中键 MK_RBUTTON按下右键 MK_SHIFT按下Shift键 MK_CONTROL按下Ctrl键 3.WM_NCHITTEST:鼠标命中测试,Windows根据它来产生与鼠标位置相关的所有其它鼠标消息 wParam unused lParam 屏幕坐标x,y 4.滑轮消息WM_MOUSEWHEEL wParam的低字组包含一系列的旗标,用于表示鼠标按键、Shift与Ctrl键的状态。 wParam的高字组保存一个「delta」值,该值目前可以是120或-120,向前转动或向后转动。值120或-120表示文件将分别向上或向下卷动三行。 lParam为鼠标的屏幕坐标
a. OnLButtonDblClk :语法为 void Object1 Wnd :: OnLButtonDblClk( UINT nFlags, CPoint point ){} ,表示控件对双击鼠标左键时的响应。
b. OnLButtonDown :语法为 void Object1 Wnd :: OnLButtonDown( UINT nFlags, CPoint point ){} ,表示控件对按下鼠标左键时的响应。
c. OnLButtonUp :语法为 void Object1 Wnd :: OnLButtonUp( UINT nFlags, CPoint point ){} ,表示控件对按下的鼠标左键放开后的响应。
d. OnRButtonDblClk :语法为 void Object1 Wnd :: OnRButtonDblClk( UINT nFlags, CPoint point ){} ,表示控件对双击鼠标右键时的响应。
e. OnRButtonDown :语法为 void Object1 Wnd :: OnRButtonDown( UINT nFlags, CPoint point ){} ,表示控件对按下鼠标右键时的响应。
f. OnRButtonUp :语法为 void Object1 Wnd :: OnRButtonUp( UINT nFlags, CPoint point ){} ,表示控件对按下的鼠标右键放开后的响应。
其中的参数 nFlags 用于指示按下的键的代码,它可以是下面的几个值或它们的组合:
MK_CONTROL 表示按下 CTRL 键 ;
MK_LBUTTON 表示按下鼠标左键;
MK_MBUTTON 表示按下鼠标中键;
MK_RBUTTON 表示按下鼠标右键;
MK_SHIFT 表示按下 SHIFT 键;
Point 参数表示鼠标的光标位置相对于所在窗口的左上角的水平和垂直坐标值。
在 VC 中用鼠标响应事件来完成人机交互中的控制功能是比较容易的。例如把一个控件 Object1 的位置移动到鼠标光标的位置,下面简单的程序就可完成:
void Object1::OnLButtonDown(UINT nFlags, CPoint point)
{
CPoint Position ;
Position = point;
Object1->left=Position.x;
Object1->top=Position.y; // 按下鼠标左键后控件的水平和垂直方向的值分别与鼠标的光标位置一致
}