mfc改变鼠标形状

http://hi.baidu.com/harbinxxh/blog/item/84248d95284548136e068c08.html 

 

Windows程序和Doc程序很大的不同就在于Windows有一个亮丽的图形界面和简捷的操作方式而鼠标就是Windows程序中最重要的一个操作手段


有朋友向我咨询如何修改鼠标形状 , 这本来是一个简单的问题 ,但是当朋友向我询问进一步的,更加深入的操作机制时 ,我才发现里面隐藏着更多的问题, 回到家里研究了一下 ,得到一些结论 。 这里就Windows下鼠标形状的一些修改方法以及一些相关API的使用 , 谈谈自己的总结 ,希望对初学者能够有所帮助。 


操作系统: Windows2000 .

开发环境: Visual C 6.0 , MFC .

示例相关类文档视图结构 , CDocTestView .


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);

你可能感兴趣的:(VC++)