首页 > 系统相关 >.NET 隐藏/自定义windows系统光标

.NET 隐藏/自定义windows系统光标

时间:2024-10-22 16:10:30浏览次数:1  
标签:IntPtr 13 鼠标 自定义 windows cursor NET public 光标

本文介绍如何操作windows系统光标。正常我们设置/隐藏光标,只能改变当前窗体或者控件范围,无法全局操作windows光标。接到一个需求,想隐藏windows全局的鼠标光标显示,下面讲下如何操作

 先了解下系统鼠标光标,在鼠标属性-自定义列表中可以看到一共有13种类型,对应13种工作状态:

操作系统提供了一组预定义的光标,如箭头、手形、沙漏等,位于 C:\Windows\Cursors目录下。

对应的Windows.Input.CursorType枚举:

 1   public enum CursorType
 2   {
 3     None,
 4     No,
 5     Arrow,
 6     AppStarting,
 7     Cross,
 8     Help,
 9     IBeam,
10     SizeAll,
11     SizeNESW,
12     SizeNS,
13     SizeNWSE,
14     SizeWE,
15     UpArrow,
16     Wait,
17     Hand,
18     Pen,
19     ScrollNS,
20     ScrollWE,
21     ScrollAll,
22     ScrollN,
23     ScrollS,
24     ScrollW,
25     ScrollE,
26     ScrollNW,
27     ScrollNE,
28     ScrollSW,
29     ScrollSE,
30     ArrowCD,
31   }

光标显示逻辑:

  • 全局光标设置:在桌面或非控件区域,使用默认系统光标。
  • 窗口控件的设置:每个窗口控件可以设置自己的光标类型。当鼠标移动到该控件上时,将自动切换到该设置的光标。如果未设置则显示系统光标
  • 当鼠标移动、点击或执行其他操作时,系统会检测并相应更新光标形状。应用程序也可以改变拖放等操作的光标

对当前鼠标状态有获取需求的,可以通过GetCursorInfo获取,当前鼠标光标id以及句柄:

1     private IntPtr GetCurrentCursor()
2     {
3         CURSORINFO cursorInfo;
4         cursorInfo.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
5         GetCursorInfo(out cursorInfo);
6         var cursorId = cursorInfo.hCursor;
7         var cursorHandle = CopyIcon(cursorId);
8         return cursorHandle;
9     }

那如何隐藏系统光标呢?系统光标可以通过SetSystemCursor function (winuser.h) - Win32 apps | Microsoft Learn函数设置,不过貌似没有隐藏光标的入口

可以换个思路,创建一个空白光标即可。我做了一个blank.cur:自己动手制作 windows鼠标光标文件(.cur格式)-CSDN博客

然后隐藏系统光标:

1   private void HideCursor()
2   {
3       _cursorHandle = GetCurrentCursor();
4       //替换为空白鼠标光标
5       var cursorFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Blank.cur");
6       IntPtr cursor = LoadCursorFromFile(cursorFile);
7       SetSystemCursor(cursor, OcrNormal);
8  }

恢复系统光标的显示,将之前光标Handle设置回去:

1 var success = SetSystemCursor(_cursorHandle, OcrNormal);

以上是实现了当前光标的替换。但上面有介绍过鼠标光标状态有13种,会根据应用程序状态进行切换,所以其它光标也要处理。

对13种光标都替换为空白光标,13种光标CursorId值在setSystemCursor文档有说明:

 1     private readonly int[] _systemCursorIds = new int[] { 32512, 32513, 32514, 32515, 32516, 32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650 };
 2     private readonly IntPtr[] _previousCursorHandles = new IntPtr[13];
 3     private void HideCursor()
 4     {
 5         for (int i = 0; i < _systemCursorIds.Length; i++)
 6         {
 7             var cursor = LoadCursor(IntPtr.Zero, _systemCursorIds[i]);
 8             var cursorHandle = CopyIcon(cursor);
 9             _previousCursorHandles[i] = cursorHandle;
10             //替换为空白鼠标光标
11             var cursorFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Blank.cur");
12             IntPtr blankCursor = LoadCursorFromFile(cursorFile);
13             SetSystemCursor(blankCursor, (uint)_systemCursorIds[i]);
14         }
15     }

运行验证:系统桌面、应用窗体如VisualStudio以及网页等光标编辑状态,都成功隐藏

还原光标状态:

1     private void ShowCursor()
2     {
3         for (int i = 0; i < _systemCursorIds.Length; i++)
4         {
5             SetSystemCursor(_previousCursorHandles[i], (uint)_systemCursorIds[i]);
6         }
7     }

用到的User32及参数类:

 1    [DllImport("user32.dll", SetLastError = true)]
 2    public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
 3    [DllImport("user32.dll")]
 4    public static extern IntPtr CopyIcon(IntPtr cusorId);
 5    [DllImport("user32.dll")]
 6    public static extern IntPtr LoadCursorFromFile(string lpFileName);
 7    [DllImport("user32.dll")]
 8    public static extern bool SetSystemCursor(IntPtr hcur, uint id);
 9    [DllImport("user32.dll")]
10    static extern bool GetCursorInfo(out CURSORINFO pci);
11 
12    [StructLayout(LayoutKind.Sequential)]
13    public struct POINT
14    {
15        public Int32 x;
16        public Int32 y;
17    }
18 
19    [StructLayout(LayoutKind.Sequential)]
20    public struct CURSORINFO
21    {
22        public Int32 cbSize;        // Specifies the size, in bytes, of the structure. 
23                                    // The caller must set this to Marshal.SizeOf(typeof(CURSORINFO)).
24        public Int32 flags;         // Specifies the cursor state. This parameter can be one of the following values:
25                                    //    0             The cursor is hidden.
26                                    //    CURSOR_SHOWING    The cursor is showing.
27        public IntPtr hCursor;          // Handle to the cursor. 
28        public POINT ptScreenPos;       // A POINT structure that receives the screen coordinates of the cursor. 
29    }
View Code

需要说明的是,系统光标修改请谨慎处理,光标修改后人工操作不太容易恢复,对应用程序退出、崩溃等情况做好光标恢复操作。

以上demo代码见:kybs00/HideSystemCursorDemo: 隐藏windows系统光标 (github.com) 

参考资料:

AllAPI.net - Your #1 source for using API-functions in Visual Basic! (mentalis.org)

createCursor 函数 (winuser.h) - Win32 apps | Microsoft Learn

SetSystemCursor function (winuser.h) - Win32 apps | Microsoft Learn

关键字:自定义光标、隐藏/显示光标、windows系统光标显示

标签:IntPtr,13,鼠标,自定义,windows,cursor,NET,public,光标
From: https://www.cnblogs.com/kybs0/p/18490299

相关文章

  • 基于模仿学习的自动泊车运动规划算法 ResNet+BERT分类模型
    本文使用ResNet+BERT分类模型来实现APA自动泊车算法首先定义模型的输出动作类别类别名说明S0停车S+直行前进单位距离S-直行后退单位距离L+左转前进单位角度L-左转后退单位角度R+右转前进单位角度R-右转后退单位角度设单位距离为0.05米,单位......
  • .NET 8 Web API从基础到提高全面示例
    .NET8WebAPI从基础到提高全面示例 概述:1.设置.NET8WebAPI项目概念使用.NETCLI创建新的WebAPI项目。这设置了一个基本的项目结构,包括启动和WeatherForecast控制器作为示例。Program.cs代码示例dotnetnewwebapi-nMyWebApi2.Program.cs—最低限度的API......
  • 024_net基于ASP.NET的视频点播系统的设计与实现2024_5gjvxer5
    目录系统展示开发背景代码实现项目案例 获取源码博主介绍:CodeMentor毕业设计领航者、全网关注者30W+群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AWS/Wired等平台优选内容创作者、深耕Web......
  • easyExcel生成excel并导出自定义样式(三)指定列字体样式
    publicclassExcelRowColorHandlerimplementsCellWriteHandler{privatefinalIntegercolumnIndex;privatefinalSet<Integer>redRowIndex;privatefinalSet<Integer>yellowRowIndex;privatefinalSet<Integer>greenRowInd......
  • 两句话讲清楚windows安装wsl和docker
    两句话讲清楚windows安装wsl和docker目录两句话讲清楚windows安装wsl和docker写在前面解决方案写在前面背景:win10/win11,微软商店打不开(打得开还不简单?能打开你直接搜别的攻略得了)准备:先直接说一个结论:不要考虑DockerDesktop,你都装wsl了,为什么还要用这玩意儿!此外,即使你想......
  • 什么是容器编排,Kubernetes如何实现
    容器编排是管理容器应用的声明式方法,确保程序在生产环境中正确部署和运行。Kubernetes作为目前领先的容器编排工具,通过1、集群管理、2、调度和自动化、3、服务发现和负载均衡、4、存储编排、5、自我修复、6、密钥与配置管理等特性实现容器编排。尤其是调度和自动化部分,Kubernetes......
  • Linux使用nc(netcat)命令检测网络端口是否畅通以及Linux查看CPU架构命令arch及CentOS
    一、Linux使用nc(netcat)命令检测网络端口是否畅通    nc命令netcat的简写,netcat即是网络猫的意思,在linux系统中nc命令实际执行命令是ncat。nc命令是一个功能强大的网络工具。平常主要用于实现TCP/UDP端口的侦听和收发,nc可作为server以TCP或UDP方式侦听指定端口,也可作为cl......
  • curl,nc和telnet的用法以及其他常用工具(nc代理与重定向)
      curl 是一个功能强大的命令行工具和库,用于在网络上传输数据。它支持多种协议,包括HTTP、HTTPS、FTP、FTPS、SFTP、SMTP、POP3、IMAP等。curl 的名称来源于“ClientforURLs”。下面是对 curl 工具的详细介绍,包括基本用法、常用选项以及实际应用场景。基本功能发送......
  • windows配置网关与netsh端口转发
            在Windows系统中,配置主机的IP地址、子网掩码和网关地址可以通过以下步骤手动设置。这在某些情况下是必要的,例如当你需要确保网络接口使用特定的IP地址或网关时。手动设置IP地址、子网掩码和网关地址的步骤打开“网络和Internet设置”:右键点击任务栏的网络......
  • windows IIS上部署Vue项目
    1.首先执行build命令打包vue项目npmrunbuild执行打包命令后生成的文件在dist文件夹内  2.新建web.config写入配置代码,放进打包后文件的根目录内https://blog.csdn.net/weixin_41934979/article/details/139711262<?xmlversion="1.0"encoding="UTF-8"?><configuratio......