在调用Windows API函数SetCursor设置光标时,可能会碰到闪烁的问题:移动鼠标,光标在Class Cursor(即注册窗口类时指定的Cursor)与预设Cursor之间闪烁。

在MSDN上有关SetCursor函数的备注中强调,如果Class Cursor非空,那么每当鼠标移动,系统都会把光标恢复为Class Cursor。为了避免光标闪烁这一问题,必须处理WM_SETCURSOR消息。(MSDN说明)

下面是一个例子:程序在主窗口视图的中间位置绘制RGB条带,当鼠标移动在条带范围就将光标设置成为Cross,此外根据光标的位置,在RGB条带上方30px处显示所处条带的颜色。程序运行起来像这样:

如果在WM_MOUSEMOVE的消息处理中判断光标的位置并设置光标的话,就会碰到所说的光标闪烁问题。WM_MOUSEMOVE的消息处理如下代码所示:

  LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/){POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };RECT rect, rectText;get_rects(&rect, &rectText);InvalidateRect(&rectText);UpdateWindow();if (::PtInRect(&rect, ptCursor)) {::SetCursor(m_cursor);int dx = (rect.right - rect.left) / 3;LPTSTR ppsz[] = { _T("Red"), _T("Green"), _T("Blue") };int index;if (ptCursor.x - rect.left < dx)index = 0;else if (ptCursor.x - rect.left < 2 * dx)index = 1;else index = 2;WTL::CString str;str.Format(_T("Cursor on %s part"), ppsz[index]);CClientDC dc(m_hWnd);dc.DrawText(str, -1, &rectText, DT_CENTER | DT_VCENTER);}else ::SetCursor(CCursor().LoadSysCursor(IDC_ARROW));return 0;}

闪烁产生的原因在于每次进入OnMouseMove之前,系统都会先将光标恢复成Arrow,进入OnMouseMove之后,如果光标处在RGB条带范围内则立即被设置成Cross。

解决办法就是将上面的判断逻辑放在WM_SETCURSOR的消息处理中,当然获得光标客户坐标的方式不同,代码如下所示:

    LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/){POINT point;::GetCursorPos(&point);ScreenToClient(&point);set_cursor(point);return 0;}

而代码中的set_cursor私有方法其实就是上面的判断逻辑,即:

 // ptCursor: in client coordinatevoid set_cursor(POINT& ptCursor) throw(){RECT rect, rectText;get_rects(&rect, &rectText);InvalidateRect(&rectText);UpdateWindow();if (::PtInRect(&rect, ptCursor)) {::SetCursor(m_cursor);int dx = (rect.right - rect.left) / 3;LPTSTR ppsz[] = { _T("Red"), _T("Green"), _T("Blue") };int index;if (ptCursor.x - rect.left < dx)index = 0;else if (ptCursor.x - rect.left < 2 * dx)index = 1;else index = 2;WTL::CString str;str.Format(_T("Cursor on %s part"), ppsz[index]);CClientDC dc(m_hWnd);dc.DrawText(str, -1, &rectText, DT_CENTER | DT_VCENTER);}else ::SetCursor(CCursor().LoadSysCursor(IDC_ARROW));}

这样就解决了光标闪烁的问题。本例的工程文件可在这里下载,它是基于WTL的SDI程序。

P.S. 另外一个问题虽然简单但仍值得一提。上面程序的截图显示的结果实际上并不准确,Cross光标的中心已经处于Green条带,但条带上方显示的却是"Cursor on Red part"。造成此问题的原因是自定义光标的热点Hot Spot默认值为(0, 0),而不是以中心+来标识的。解决办法是在VS资源编辑器中使用Hot Spot Tool,如下图所示:

点击Cross光标的中心点,热点坐标将变成你所设置的值,如下图所示:

光标闪烁问题的解决办法相关推荐

  1. FANUC机器人UO【7】At Perch机器人就位信号闪烁问题的解决办法

    关于FANUC机器人UO[7]At Perch机器人就位信号闪烁问题的解决办法 Fanuc机器人系统可以定义十个参考位置,当机器人位于第一个参考位置时,该信号输出为ON.这是说明书上对于UO[7]At ...

  2. Win32关于调整窗口大小时,窗口闪烁问题及解决办法

    先来谈谈闪烁产生的原因 : 原因一: 如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕 上只是写到了显存里,而显卡每隔一段时间把显存的内容输出到屏幕上,这就是刷新周期. 一般 ...

  3. python 程序化交易信号闪烁_程序化交易模型的信号闪烁问题及解决办法

    来源:雪球App,作者: 高低之间_简单价投,(https://xueqiu.com/2853948193/86030837) 1.程序化交易模型的信号闪烁问题 所谓信号闪烁,是指程序化交易模型在图表 ...

  4. win10一按右键就闪屏_升级Win10正式版后屏幕一直闪烁正确的解决办法

    Win10正式版屏幕一直闪烁怎么办呢?升级到Win10正式版并进入Windows桌面后,发现屏幕一直不断的闪烁,此时无法执行任务操作.小编最近在升级到Win10正式版后才遇到了这个问题,后台经过反复思 ...

  5. [MFC] 界面闪烁若干种解决办法

    界面闪烁原因,可以参考这里 总结了工作中使用过的如下几种方法 ,具体原理就不说了,如果有相应的UI开发经验 应该很容易懂,不懂的话根据我提供的关键字自己搜索一下具体原理. 1.双缓冲 这个是最基本的 ...

  6. JetBrains系列WebStorm等中文输入法无法跟随光标的问题的解决办法

    参考:https://blog.csdn.net/wang414300980/article/details/79537875 电脑配置: 解决这个问题的思路就是修改启动软件的JDK,有以下几个方法: ...

  7. JQuery slideToggle闪烁问题及解决办法

    近期进行的一个项目中,对侧边的菜单栏进行操作,为了达到缓慢隐藏或者出现的效果,选择使用jquery的slideToggle()方法.但是发现效果表现并不理想.在单个案例中,可以像在http://www ...

  8. PyCharm使用(一)-光标变成黑色方块解决办法

    PyCharm使用遇到的问题一 Q1:使用pycharm编译器时,经常出现误碰触键盘导致光标变成黑色粗方块; A1:按"Insert"键,光标恢复正常.

  9. python光标变粗_PyCharm光标变粗的解决办法

    iOS开发--二维码的生成 一.需要包含头文件 #import 二.示例代码 -- 以下生成的二维码不够清晰 如图: - (void)touchesBegan:(NSS ... 火箭18号秀光膀为父母 ...

最新文章

  1. 银监会警示担保圈贷款风险 联保贷款变异 防多米诺效应
  2. linux 实验 广技师 进程管理与系统监视,Linux系统管理之进程管理
  3. _ctypes.COMError: (-2147024809, '参数错误。', (None, None, None, 0, None))
  4. Algorithm:C+语言实现之数组相关算法(和为定值的两个数、和为定值的m个数、荷兰国旗、长度为2n的洗牌算法、任意长度数组的洗牌算法)
  5. mysql 秒杀 隔离级别_MySQL 四种隔离级别详解,看完吊打面试官
  6. MSP430F5529 DriverLib 库函数学习笔记(六)定时器A产生PWM波
  7. 华科08年计算机考研复试机试
  8. mysql and 和where_如何使用mysql查询where条件里的or和and
  9. 麦块服务器显示连接已丢失,麦块服务器密码怎么设置
  10. argb可以和rgb同步吗_更冷更静更降温!第三代双腔设计,酷冷至尊海魔240水冷岂止RGB...
  11. Qt_共享内存(QSharedMemory)未完成
  12. ECSHOP商城网站建设之自定义调用广告方法(二)
  13. K8s CKS认证学习全套笔记
  14. syntax error : missing ';' before identifier 'oper'解决方法
  15. 中级维修电工实训装置
  16. matlab 第二版 赵元哲 下载,基于MATLAB的黑盒电路仿真设计及应用
  17. 基于python的微博舆情分析与研究—以《北京冬奥会》为关键词
  18. 什么模拟器可以完全模拟真机_什么是模拟器?
  19. MATLAB 四点定球及三点定圆(完整代码)
  20. cs程序上传文件至web服务器,asp.net 程序上传到导服务器发生异常

热门文章

  1. python requests_小白学 Python 爬虫(18):Requests 进阶操作
  2. openCV实战(一):rectangle函数使用
  3. Python几个简单好用的基础功能
  4. 【图像处理】MATLAB:退化函数及多种复原方法
  5. 中国生物医药行业供需形势透析及未来投资风险评估报告2022-2027年版
  6. COM 组件设计与应用(十一)—— IDispatch 及双接口的调用
  7. php layui实现添加input,Layui实现input输入和选择的方法
  8. 【转】Linux开机启动管理---systemd使用
  9. JavaScript 中的原型(总则)
  10. 对象的克隆(clone方法)