鼠标光标的一个“看起来”很神奇的问题

【python实用小脚本系列】用Python让鼠标“动起来”:光标自动移动、自动点击、自动图象识别的小技巧 通过今天的分享,你是不是觉得用Python控制鼠标其实并不难?这个简单的脚本虽然只有几行代码,但却非常实用。你可以根据自己的需求进行扩展,让它在更多的场景中发挥作用。无论是防止电脑睡眠,还是模拟用户操作,它都能帮你实现。需要完整的源码,请在评论区留言,或私信我。 阅读详情

Windows里最让人抓狂的问题,莫过于鼠标相关的BUG了(估计所有GUI程序都一样)。鼠标的BUG往往还不能直接打断点调试,只能结合日志信息,加上自己的经验一起来查,这就更是难上加难了。

 

最近遇到一个问题,虽然很快解决了,但解决过程自觉还是很典型的。

 

问题是这样的:我们的程序主窗口上有一些区域鼠标移上要变手形光标,移开恢复箭头光标。原来一直是正常的,但一个新版本开发了一周后合出来后,发现光标变成手形后,不再恢复了。

 

我们的这个主窗口的C++类继承关系是这样的:

CMainWindow -> CSkinFrameWindow -> CSkinWindow -> CWnd

 

程序是在OnSetCursor里设置光标的,初步的猜测是OnSetCursor没有被调用到。由于WM_SETCURSOR消息是在WM_MOUSEMOVE事件前收到的,所以预计会收到很多次。于是在OnMouseMove和OnSetCursor里,都打上了日志。结果发现WM_SETCURSOR消息正常。

 

这说明系统的鼠标消息机制没有出奇怪的问题。这给我了很大信心,至少不用查消息为什么没有发出来这样变态的问题了。这样就说明,一定是我们的代码里哪出现问题了。

仔细看OnSetCursor的代码:

    BOOL result = FALSE;

    if (enmMouseType_Hand == m_eMouseType)

    {

        HCURSOR hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));

        SetCursor(hCursor);

        result = TRUE;

    }

    else if (enmMouseType_Disable == m_eMouseType)

    {

        HCURSOR hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR_DISABLE_BIG);

        SetCursor(hCursor);

        result = TRUE;

    }

    else

    {

        result = __super::OnSetCursor(pWnd,nHitTest,message);

    }

    return result;

 

继续打日志,发现m_eMouseType的值没有问题,在正确的时机都被正确的赋值了。因此,基本确认问题出在标红的一句,这一个分支就是处理把鼠标变成箭头的。但调试下来的结果是似乎这一句没起作用。

在这一句打了断点后,发现,基类的OnSetCursor返回FALSE,这说明基类的默认处理没有修改鼠标光标。再看我们自己写的基类,发现没有OnSetCursor代码,因此这里调用的是CWnd::OnSetCursor()。

 

在MSDN里查CWnd::OnSetCursor发现以下内容:

 

The default implementation calls the parent window's OnSetCursor before processing. If the parent window returns TRUE, further processing is halted. Calling the parent window gives the parent window control over the cursor's setting in a child window.

The default implementation sets the cursor to an arrow if it is not in the client area or to the registered-class cursor if it is.

 

也就是说,默认的处理是:

1.  如果光标不在客户区,就设置成箭头

2.  否则设置成窗口类注册时指定的光标

 

看来,是窗口类的问题了。用Beyond Compare查了一下最近的修改历史,发现我们的CMainWindow::Create()函数原来是调用基类的CSkinWindow::Create()来创建窗口的。而基类中注册窗口类时指定了箭头光标:

 

BOOL CSkinWindow::Create(HWND hwndParent,

                         const RECT& rect,

                         DWORD dwStyle)

{

    return CWnd::CreateEx(

        0,

        AfxRegisterWndClass(CS_DBLCLKS,::LoadCursor(NULL, IDC_ARROW)),

        L"",

        dwStyle,

        rect.left,

        rect.top,

        rect.right  - rect.left,

        rect.bottom - rect.top,

        hwndParent,

        NULL);

}

 

 

而改动之后,CMainWindow::Create()不再调用基类的这个Create,而是使用了另一个窗口类来创建窗口:

 

BOOL CMainWindow::Create(RECT rcInitialPosition)

{

    return CWnd::CreateEx(

        0,

        L"MainWindowClass",

        L"MainWindow",

        WS_OVERLAPPED | WS_VISIBLE| WS_OVERLAPPEDWINDOW| WS_CLIPCHILDREN,

        rcInitialPosition.left,

        rcInitialPosition.top,

        rcInitialPosition.right  - rcInitialPosition.left,

        rcInitialPosition.bottom - rcInitialPosition.top,

        NULL,

        NULL);

}

 

再在工程中查找"MainWindowClass"这个串,发现以下注册窗口类代码:

 

BOOL CMainApp::InitInstance()

{

    WNDCLASS wndclass;

    wndclass.hInstance = AfxGetInstanceHandle();

    wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

    wndclass.cbClsExtra = 0;

    wndclass.cbWndExtra = 0;

    wndclass.hCursor = NULL;

    wndclass.hIcon = NULL;

    wndclass.lpszMenuName = NULL;

    wndclass.lpfnWndProc = ::DefWindowProc;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;

    wndclass.lpszClassName = L"MainWindowClass";

    wndclass.hCursor = NULL;

    bRet = AfxRegisterClass(&wndclass);

 

    return CWinApp::InitInstance();

}

 

事情真相大白了,新的这个窗口类注册时没有指定光标,默认处理不会自作主张的把光标改成一个箭头,于是,本应当变成箭头的分支实际上没做任何处理。

 

修改也很简单了,注册窗口类时,指定箭头光标就好:

wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);

 

结论:

1.  不要因为调用基类的OnSetCursor没起作用,就认为是系统的什么神奇问题。几乎所有情况下,Windows经受的测试都比你的代码多,一定是你的代码出的问题。

2.  一定要有刨根问底的精神,不要在OnSetCursor那里想办法绕过,而是应当知道为什么一段你认为应当起作用的代码没起作用,什么情况下它才会发挥你想象中的作用。

一个神奇的GUI自动化测试库-PyAutoGui 看到这个库的时候,单单从名字就感觉到两个字“简单”,特别容易理解它是用来做什么的,深入了解之后感觉的还是两个字“简单”。这对自动化测试来说便是一个天大的乐事,因为很多工具庞大复杂,仅仅是写一个hello world需要的环境,需要了解的东西比c++,java还难。 PyAutoGUI作为GUI自动化神器,简单高效、函数分类清晰,它被awesome-python、awesome-python-cn收录 现在我就带你们走进PyAutoGUI~ 1. PyAutoGui是什么? PyAutoGui是一 阅读详情

相关推荐

OpenDRIVE车道计算避坑指南:为什么你的poly3曲线总对不齐?

本文深入解析OpenDRIVE标准中车道几何计算的三大核心难题:参数化三次多项式(ParamPoly3)的坐标系转换与参数映射、车道偏移与宽度的优先级判定,以及螺旋线(Spiral)接续的平滑性保障。通过实战案例与代码示例,提供了一套避免车道线错位与曲率不连续的精确计算与验证方法,是高精地图开发与仿真场景构建的实用避坑指南。

q9w8e7r6t5的博客 424

OnSetCursor 及改变鼠标形状

该消息在鼠标发生任何事件时都能响应(单击,双击,移动,且该函数的调用在对于鼠标响应函数之前)。 如果处理了该函数,一定要返回return TRUE,不要让父类再处理 该函数专门由于设置光标的形状,是对WM_SETCURSOR消息的响应. afx_msg BOOL CWnd::OnSetCursor(CWnd* pWnd,UINT nHitTest,UINT message); 参数一...

baidu_16370559的博客 1736

HyperLynx实战:手把手教你搞定DDR4信号完整性仿真(附ODT与终端电阻配置避坑)

本文详细介绍了使用HyperLynx进行DDR4信号完整性仿真的实战技巧,重点解析了ODT配置与终端电阻优化的黄金法则。通过模型准备、拓扑构建、ODT扫描等关键步骤,帮助硬件工程师规避常见设计陷阱,提升高速数字电路设计的效率与可靠性。

weixin_30861797的博客 640

OnSetCursor由消息 WM_SETCURSOR 触发 The WM_SETCURSOR message is sent to a window if the mouse causes th

OnSetCursor由消息 WM_SETCURSOR 触发  The WM_SETCURSOR message is sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured. 看清楚了,只要鼠标移动OnMouseMOve就会自动发

tianyu的专栏 - Linux site:blog.youkuaiyun.com/wishfly 5153

SAP MTS计划策略40实战:如何配置‘带最终组装的计划‘提升定制化生产效率

本文深入解析SAP计划策略40(带最终组装的计划)的核心机制与实战配置。该策略通过“需求消耗”与“组装灵活性”,有效融合按库存生产(MTS)与按订单生产(MTO)的优势,帮助制造企业在保持通用组件库存稳定的同时,快速响应客户的定制化需求,从而提升生产效率与客户满意度。

ruby5的博客 968

嵌入式工程师必看:BLDC电机驱动电路设计全流程(附MOS管选型指南)

本文为嵌入式工程师提供了BLDC电机驱动电路设计的全流程实战指南。文章深入解析了三相全桥逆变电路的核心原理,并重点阐述了功率MOSFET的选型关键参数,如Vds、Rds(on)和Qg。同时,详细介绍了栅极驱动设计、PCB布局布线要点及调试安全步骤,旨在帮助开发者构建稳定高效的BLDC驱动系统。

weixin_29194817的博客 589

设置鼠标光标的手型

VC++ 6.0 设定光标可以使用SetCursor(HCURSOR hCursor)来设定,如果是新手,建议在WM_SETCURSOR消息响应函数中设置,你可以在别的地方设置,但是需要自己控制光标的变化。 1、使用系统预定义的光标: 使用ClassWizard为视图或者对话框添加WM_SETCURSOR消息的响应函数OnSetCursor();在函数中,使用Set...

qq_43080331的博客 1786

从零到一:Mx_yolo本地训练与K210部署实战指南

本文详细介绍了从零开始进行Mx_yolo本地模型训练到K210部署的全流程实战指南。涵盖环境配置、数据准备、模型训练与调优、模型转换及K210部署等关键步骤,并提供了常见问题解决方案和性能优化技巧,帮助开发者高效完成AI模型在嵌入式设备的落地应用。

weixin_29081163的博客 252

VC 鼠标消息WM_SETCURSOR

VC 鼠标消息WM_SETCURSOR   OnSetCursor由消息   WM_SETCURSOR   触发      The   WM_SETCURSOR   message   is   sent   to   a   window   if   the   mouse   causes   the   cursor   to   move   within   a   w

djf_1985的专栏 2902

CloudCompare 二次开发:插件中的 PCL 环境配置与编程

在进行 CloudCompare 的二次开发过程中,我们常常需要使用点云库(Point Cloud Library,简称 PCL)来处理和分析点云数据。在 CloudCompare 的界面中,选中一个点云对象,然后点击菜单栏中的 “插件” -> “MyPluginAction”。插件将对选中的点云对象进行体素滤波处理,并更新显示结果。下面我们将展示一个简单的插件编程示例,该示例使用 PCL 对输入的点云数据进行体素滤波处理。方法进行体素滤波处理,并将结果点云赋值给选中的点云对象。文件并点击 “打开”。

2301_79331387的博客 283

机器人控制基础:伺服驱动电机 PID 参数自适应控制的实现方法及研究

伺服电机PID参数自适应控制技术研究 摘要:针对伺服驱动电机在动态负载工况下传统PID控制性能下降的问题,本文研究了多种自适应控制方法。通过分析6种主流技术(包括模型参考自适应、模糊逻辑、神经网络等)的原理、实现步骤及适用场景,揭示了负载感知精度、参数调节实时性和系统稳定性三大技术难点,并提出了相应解决方案。以模糊自适应PID为例的实验验证表明,该技术能有效提升伺服系统在变负载条件下的控制性能。研究为工业应用中伺服电机的精确控制提供了重要参考。

start_up_go的博客 828

神奇"光标" 鼠标指针在城市自由移动

  神奇"光标" 鼠标指针在城市自由移动 鼠标指针在屏幕上的移动对我们来说已经司空见惯,但是国外的艺术家们总是能给我们更多想象的空间,在西班牙加泰隆尼亚一个公园内,一个超大的三维鼠标指针工艺品亮相,而它的功能还仅仅是展示。(注:图片来源于互联网)超大鼠标“指针”  超大鼠标“指针”超大鼠标“指针”    其实这个鼠标不同于

xuehuic的成长 974

Megatron-LM中的TP、PP、DP、SP、CP并行

SP主要优化的是激活内存,它沿序列维度切分部分激活,适用于较短序列并行。CP主要解决的是长序列的显存问题,它沿序列维度切分所有激活和输入,并且对注意力机制也进行并行处理。二者可以组合使用,特别是当 TP > 1 并且需要处理长序列时,通过启用 SP 和 CP 可以最大化地优化内存使用和加速计算。

u013250861的博客 861

opencv 改变光标_在OpenCV中,放大图像后,如何返回到标准鼠标光标?

我有一个应用程序,我裁剪图像的一部分,并使用Python将它们保存在opencv4中,在保存之前首先绘制矩形(下面是ssce)。有些图像非常大,所以在选择要裁剪的区域之前放大它们是很有帮助的。在问题是,一旦你缩放了一个图像,鼠标光标就会永久地切换到交互式手上。然后单击/拖动只用于在窗口中转换图像的位置(除非我返回到全尺寸,但是我不能在放大的图像上绘制矩形)。在所以我的问题是,一旦我放大,我如何从中...

weixin_42299018的博客 408

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

如何用Mousecape拯救你的Mac鼠标:3步打造专属个性光标体验

还记得那个让我抓狂的下午吗?我在深色主题的代码编辑器里找了整整五分钟光标——那个该死的白色箭头在黑色背景里就像隐形了一样。作为一名设计师兼程序员,我受够了Mac系统千篇一律的鼠标指针。直到我遇见了Mousecape,这个神奇的鼠标光标定制工具,它彻底改变了我的工作体验。今天,我要分享这段从"找光标"到"玩转光标"的完整历程,让你也能轻松打造属于自己的个性化鼠标体验。 ## 我的痛点:当鼠标指针成

gitblog_00690的博客 852

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

厌倦了Mac的单调光标?用Mousecape打造属于你的个性化鼠标指针

你是否每天盯着Mac上那个一成不变的白色箭头,感觉它就像办公室里永远穿白衬衫的同事一样无聊?鼠标指针作为我们与电脑互动最频繁的元素,却往往被忽视其个性化潜力。今天,我要向你介绍一款能让你的Mac光标焕然一新的神奇工具——**Mousecape**,这款**Mac光标管理器**将彻底改变你对鼠标指针的认知。 **核心关键词:Mac光标管理器** **长尾关键词:鼠标指针自定义、光标主题更换、个

gitblog_00422的博客 888

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

5分钟免费定制Mac鼠标指针:Mousecape终极光标管理器完全指南

你是否厌倦了Mac上那个千篇一律的白色箭头鼠标指针?想让你的数字生活更有趣、更个性化?今天我要为你介绍一款神奇的Mac光标管理器——Mousecape。这款免费的光标自定义工具能让你轻松改变鼠标指针的外观,为日常工作增添无限乐趣。作为一款专业的鼠标指针管理器,它通过macOS私有API实现安全无侵入的光标定制,让你的光标从工具变成艺术品。 ## 🌟 为什么你的Mac需要个性化鼠标指针? 每天

gitblog_00301的博客 1099

如何快速打造个性化光标:5个简单步骤告别单调鼠标指针

你是否厌倦了Mac系统千篇一律的白色箭头光标?每天盯着那个小小的、毫无个性的指针,是否让你感到视觉疲劳?现在,有一个神奇的解决方案能让你的数字工作空间焕然一新!Mousecape是一款专业的Mac鼠标指针个性化工具,让你轻松告别单调,拥抱创意无限的光标世界。无论你是程序员、设计师还是普通用户,这款免费工具都能让你的鼠标指针与众不同! ## 为什么你需要个性化鼠标指针? 想象一下,你每天与电脑互

gitblog_00156的博客 530

dsh-purge 实测:破甲提示词按模型切换,国模评测从此可归因

用 DeepSeek Harness 换模型做提示词评测时,最容易误判的是「拒绝」——问题往往不在模型,而在宿主运行时改提示词、加审批门。dsh-purge 是装在本机官方 Harness 上的插件:清洗宿主默认人设、注入按模型可切换的破甲提示词,面向国模的默认人设叫「小码酱」。 ## 它动过什么、没动过什么:dsh-purge 的作用边界 先划清范围:它只作用于你自己本机已安装的官方 Dee

gitblog_00934的博客 945

你的鼠标指针也能变成香蕉?揭秘香蕉光标主题的创意玩法

你知道吗?每天陪伴你点击、拖拽的鼠标指针,其实可以变得如此有趣!香蕉光标主题(banana-cursor)让普通的箭头变身成生动香蕉,从22px到200px多种尺寸随心定制,为你的数字生活注入满满活力。 ## 🎯 香蕉光标在不同场景中的神奇应用 **创意工作场景**:当设计师在Figma中调整图层时,香蕉光标宛如在屏幕上"跳跃",让枯燥的设计过程变得轻松愉快。程序员在编写代码时,香蕉指针的旋

gitblog_00454的博客 541

终极指南:如何在Mac上实现光标自由?Mousecape隐藏的5个神奇技巧

想象一下,你的Mac光标不再是一个单调的白色箭头,而是随着你的心情、工作状态甚至当前应用而变化的个性化艺术品。当你在设计软件中工作时,它变成了一支精致的画笔;当你在编程时,它变成了闪烁的代码符号;当你需要专注时,它变成了一个优雅的沙漏。这不是未来的幻想,而是Mousecape带给你的现实——一款基于苹果私有CoreGraphics API构建的免费光标管理器,为macOS 10.8+用户打开了一扇

gitblog_01126的博客 661

告别鼠标手!MouseClick鼠标连点器与光标美化工具完全指南

你是否曾在深夜面对重复的点击任务感到手腕酸痛?是否羡慕别人电脑上那些酷炫的鼠标光标?今天我要分享一个能同时解决这两个痛点的神奇工具——MouseClick鼠标连点器。这款基于Qt6开发的跨平台软件,不仅能自动化你的重复点击工作,还能让你拥有个性化的光标体验,彻底提升你的数字工作效率和桌面美观度。 ## 从游戏到办公:那些让你头疼的点击场景 想象一下这些场景:在MMORPG游戏中需要连续点击采集

gitblog_01128的博客 177

终极指南:如何用JavaScript和CSS创建神奇的用户光标控制效果

Control User Cursor是一个令人惊叹的开源实验项目,它展示了如何使用JavaScript和CSS技术来"控制"用户光标,创造出独特的交互体验。这个创新项目为前端开发者提供了一个绝佳的学习案例,展示了如何突破传统光标交互的限制。 ## 什么是Control User Cursor? Control User Cursor是一个小型但功能强大的实验项目,它通过JavaScript和

gitblog_00071的博客 453

让你的macOS光标焕然一新:Mousecape完全攻略

厌倦了千篇一律的macOS默认光标?想要打造独一无二的桌面体验吗?Mousecape作为一款专业的macOS光标管理器,能够让你的鼠标指针彻底改头换面。今天,我们将从零开始,带你全面掌握这款神奇工具的使用技巧。 ## 初见Mousecape:界面初探与功能概览 打开Mousecape,你会看到一个简洁而强大的界面。左侧是丰富的主题库,右侧是实时预览区域。无论是简洁的现代风格,还是可爱的卡通形象

gitblog_01145的博客 649

终极Mac鼠标指针个性化指南:如何用Mousecape打造与众不同的光标体验

厌倦了Mac系统千篇一律的白色箭头光标?想要为你的数字工作空间注入个性和活力吗?今天我要向你介绍一个神奇的Mac鼠标指针管理神器——Mousecape!这款免费的开源工具让你能够轻松定制和更换系统光标主题,为日常电脑使用增添无限创意可能。无论你是追求效率的程序员、注重审美的设计师,还是希望提升工作乐趣的普通用户,Mousecape都能满足你的个性化需求。 ## 为什么你的Mac需要个性化鼠标指针

gitblog_00618的博客 704
上一篇: 条件断点引发的血案
下一篇: 今天这个BUG再次证明了,凡事有果必有因
BalonFan
博客等级 码龄26年 47粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值