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

【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是一 阅读详情

相关推荐

Perplexity AI 高效使用培训手册

Perplexity AI 是一款革命性的 AI 搜索引擎,提供免费版和专业版两种选择。免费版支持基础搜索、每日3次Pro搜索、3个文件上传和初步深度研究功能;Pro版则解锁无限次Pro搜索、无限制文件上传、AI图像生成等高级功能,适合专业用户深度研究。该工具能整合网络信息、分析本地文档、生成创意内容,并提供知识库管理功能,显著提升信息检索和内容创作效率。用户可根据需求选择合适版本,免费版已能满足日常使用,而Pro版则更适合专业场景。

conquer_qgw的博客 1207

OnSetCursor 及改变鼠标形状

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

baidu_16370559的博客 1736

CH341的I2C流模式(StreamI2C)到底怎么用?从EEPROM读写到自定义设备,一篇讲清参数配置逻辑

本文详细解析了CH341的I2C流模式(StreamI2C)的使用方法,从EEPROM读写到自定义设备的参数配置逻辑。通过深入分析I2C协议基础、StreamI2C参数映射关系及典型设备配置示例,帮助开发者快速掌握StreamI2C的应用技巧,解决实际开发中的常见问题。

weixin_30932215的博客 449

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

电商项目功能简述

1.电商行业的技术特点 1.技术性 2.技术范围广 3.分布式 4.高并发,集群,负载均衡,高可用 5.海量数据 6.业务复杂 7.系统安全 2.电商行业的模式 B2B:企业到企业,商家到商家.代表:阿里巴巴 B2C:商家到客户.代表:京东.淘宝商城 C2C:客户到客户.淘宝集市 O2O:线上到线下 3.B2C电商系统架构功能模块 4.B2C电商系统架构功能描述 后台管理系统:管理商品、订单、类...

weixin_45116848的博客 9744

5款高性价比LDO芯片实测对比:从TPS7A4501到LM2940,哪款更适合你的项目?

本文通过实测对比了TPS7A4501、TPS72301、LM2937、LM2940等五款高性价比LDO芯片的核心性能。文章详细分析了跌落电压、输出噪声、静态电流及热性能等关键指标,并结合电池供电物联网节点、高精度数据采集等典型应用场景,提供了清晰的选型指南,帮助工程师根据项目需求选择最合适的LDO芯片。

weixin_29305337的博客 116

设置鼠标光标的手型

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

qq_43080331的博客 1786

51单片机-点亮LED和蜂鸣器

ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。ULN2003是大电流驱动陈列,多用于单片机、只能仪表、PLC、数字量输出卡等控制电路中。可直接驱动蜂鸣器、继电器等负载。void delay(u16 i) // i等于1大约10uswhile(i--);//取反,高低电平不断变化,产生脉冲delay(10);// 周期200us。

三日沐水 1128

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

独立游戏之路:Tap篇 -- 个人开发者上架TapTap步骤和注意事项

作为一名游戏开发者,将自己的独立游戏上架到 TapTap 平台是一个不错的选择。TapTap 是一个拥有大量用户的游戏社区平台,上架游戏可以让更多的玩家发现和体验你的游戏。TapTap 是一个游戏社区平台,用户可以在平台上下载和分享游戏。TapTap 拥有大量的用户,并且用户活跃度高,这为独立游戏开发者提供了一个很好的展示和推广平台。进入TapTap开发者服务后台。

陈言必行 -- Unity游戏开发领域优质博主 6417

计算机视觉(角点检测)- 1 - Harris角点检测

计算机视觉(角点检测)-1.1 Harris角点检测学习前言 学习前言   今天更新一下计算机视觉的东西吧,哈哈哈o( ̄︶ ̄)o   关于角点检测呢,就是检测图像中角点的算法,常见的有四种常见的算法:Moravec角点检测算法、 Harris角点检测算法、Shi-Tomasi 算法、FAST角点检测算法,不过常用的就两种吧——Harris角点检测算法、Shi-Tomasi 算法(反正我基本上就只用到这两种,先着重介绍前面两种,后面再花世界介绍吧)(~ ̄▽ ̄)~ ...

qq_40374812的博客 1万+

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

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

xuehuic的成长 974

基于YOLOv8的水果新鲜程度检测系统设计与实现

数据采集与预处理模块:负责收集水果图像数据并进行标注和增强深度学习模型:基于YOLOv8的目标检测模型新鲜度评估模块:根据检测结果评估水果新鲜程度用户界面:提供友好的交互界面系统集成:将各模块整合为完整系统水果新鲜程度检测需要包含多种水果在不同新鲜度状态下的图像数据集。:包含5种常见水果(苹果、香蕉、橙子、葡萄、草莓)在不同新鲜度下的图像包含约8,000张图像,分为新鲜和腐烂两类AgriVision:大型农业图像数据集,包含水果检测和分类任务Fruit-360:包含120种水果的高质量图像。

YOLO 445

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

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

weixin_42299018的博客 408

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

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

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

gitblog_00690的博客 852

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

gitblog_00422的博客 888

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

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、付费专栏及课程。

余额充值