WM_SETCURSOR消息

最近写一个拖拉无标题对话框改变大小的程序,这就需要用到改变程序的光标。最开始设想在消息WM_MOUSEMOVE中判断光标位置,改变光标形状,但是发现有光标的闪烁现象。baidu了一下,说是应该在WM_SETCURSOR消息中设置光标。这在Using Cursor文档中有说明。

Your application can change the design of the cursor by using the SetCursor function and specifying a different cursor handle. However, when the cursor moves, the system redraws the class cursor at the new location. To prevent the class cursor from being redrawn, you must process the WM_SETCURSOR message. Each time the cursor moves and mouse input is not captured, the system sends this message to the window in which the cursor is moving.

意思是说应用程序可以使用API SetCursor改变光标,但是当光标移动时,系统会在新的位置绘制类光标(class cursor),也就是注册窗口类时指定的光标。为了防止绘制类光标,你应该处理WM_SETCURSOR消息。光标移动并且没有鼠标输入时,系统会向窗口发送这个消息。

我的这个对话框还有一些子窗口,但是光标移动到子窗口时,发现光标没有被还原为子窗口的光标。这是什么情况呢?我是使用的WTL开发的对话框,其WM_SETCURSOR消息响应函数为

BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message)
很明显第一个参数为窗口句柄,这就奇怪了,我就是在这个窗口里移动光标时就会调用这个函数啊,这个wnd参数不就是我正在其移动光标的窗口吗?我打印了下wnd值,发现光标在子窗口移动时也会调用这个消息处理函数。我不得不又翻看msdn文档 WM_SETCURSOR message,里面有这样的表述:

The DefWindowProc function passes the WM_SETCURSOR message to a parent window before processing. If the parent window returns TRUE, further processing is halted. Passing the message to a window's parent window gives the parent window control over the cursor's setting in a child window. The DefWindowProc function also uses this message to set the cursor to an arrow if it is not in the client area, or to the registered class cursor if it is in the client area. If the low-order word of the lParam parameter is HTERROR and the high-order word of lParam specifies that one of the mouse buttons is pressed, DefWindowProc calls the MessageBeep function.

DefWindowProc 会将消息WM_SETCURSOR发送给父窗口,如果父窗口返回TRUE,表示父窗口要求给子窗口设置光标,子窗口无需再处理此消息。DefWindowProc 会将光标设置为箭头光标如果光标不在客户区,如果在客户区,将光标设置为类光标。如果lParam 的低字节为HTERROR,高字节lParam 表示一个鼠标按钮被按下,DefWindowProc 将调用MessageBeep 函数。

大多数情况下,当nHitTest为 HTCLIENT时设置光标,不是客户区时交由系统设置。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值