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

打印 上一主题 下一主题

主题 884|帖子 884|积分 2652

本文介绍怎样操作windows体系光标。正常我们设置/隐藏光标,只能改变当前窗体大概控件范围,无法全局操作windows光标。接到一个需求,想隐藏windows全局的鼠标光标显示,下面讲下怎样操作
 先了解下体系鼠标光标,在鼠标属性-自定义列表中可以看到一共有13种类型,对应13种工作状态:

操作体系提供了一组预定义的光标,如箭头、手形、沙漏等,位于 C:\Windows\Cursors目次下。
对应的Windows.Input.CursorType摆列:
  1. 1   public enum CursorType
  2. 2   {
  3. 3     None,
  4. 4     No,
  5. 5     Arrow,
  6. 6     AppStarting,
  7. 7     Cross,
  8. 8     Help,
  9. 9     IBeam,
  10. 10     SizeAll,
  11. 11     SizeNESW,
  12. 12     SizeNS,
  13. 13     SizeNWSE,
  14. 14     SizeWE,
  15. 15     UpArrow,
  16. 16     Wait,
  17. 17     Hand,
  18. 18     Pen,
  19. 19     ScrollNS,
  20. 20     ScrollWE,
  21. 21     ScrollAll,
  22. 22     ScrollN,
  23. 23     ScrollS,
  24. 24     ScrollW,
  25. 25     ScrollE,
  26. 26     ScrollNW,
  27. 27     ScrollNE,
  28. 28     ScrollSW,
  29. 29     ScrollSE,
  30. 30     ArrowCD,
  31. 31   }
复制代码
光标显示逻辑:

  • 全局光标设置:在桌面或非控件区域,使用默认体系光标。
  • 窗口控件的设置:每个窗口控件可以设置本身的光标类型。当鼠标移动到该控件上时,将自动切换到该设置的光标。如果未设置则显示体系光标
  • 当鼠标移动、点击或实行其他操作时,体系会检测并相应更新光标外形。应用步伐也可以改变拖放等操作的光标
对当前鼠标状态有获取需求的,可以通过GetCursorInfo获取,当前鼠标光标id以及句柄:
  1. 1     private IntPtr GetCurrentCursor()
  2. 2     {
  3. 3         CURSORINFO cursorInfo;
  4. 4         cursorInfo.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
  5. 5         GetCursorInfo(out cursorInfo);
  6. 6         var cursorId = cursorInfo.hCursor;
  7. 7         var cursorHandle = CopyIcon(cursorId);
  8. 8         return cursorHandle;
  9. 9     }
复制代码
那怎样隐藏体系光标呢?体系光标可以通过SetSystemCursor function (winuser.h) - Win32 apps | Microsoft Learn函数设置,不外貌似没有隐藏光标的入口
可以换个思路,创建一个空白光标即可。我做了一个blank.cur:本身动手制作 windows鼠标光标文件(.cur格式)-CSDN博客
然后隐藏体系光标:
  1. 1   private void HideCursor()
  2. 2   {
  3. 3       _cursorHandle = GetCurrentCursor();
  4. 4       //替换为空白鼠标光标
  5. 5       var cursorFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Blank.cur");
  6. 6       IntPtr cursor = LoadCursorFromFile(cursorFile);
  7. 7       SetSystemCursor(cursor, OcrNormal);
  8. 8  }
复制代码
恢复体系光标的显示,将之前光标Handle设置回去:
  1. 1 var success = SetSystemCursor(_cursorHandle, OcrNormal);
复制代码
以上是实现了当前光标的更换。但上面有介绍过鼠标光标状态有13种,会根据应用步伐状态进行切换,以是其它光标也要处理。
对13种光标都更换为空白光标,13种光标CursorId值在setSystemCursor文档有说明:
  1. 1     private readonly int[] _systemCursorIds = new int[] { 32512, 32513, 32514, 32515, 32516, 32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650 };
  2. 2     private readonly IntPtr[] _previousCursorHandles = new IntPtr[13];
  3. 3     private void HideCursor()
  4. 4     {
  5. 5         for (int i = 0; i < _systemCursorIds.Length; i++)
  6. 6         {
  7. 7             var cursor = LoadCursor(IntPtr.Zero, _systemCursorIds[i]);
  8. 8             var cursorHandle = CopyIcon(cursor);
  9. 9             _previousCursorHandles[i] = cursorHandle;
  10. 10             //替换为空白鼠标光标
  11. 11             var cursorFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Blank.cur");
  12. 12             IntPtr blankCursor = LoadCursorFromFile(cursorFile);
  13. 13             SetSystemCursor(blankCursor, (uint)_systemCursorIds[i]);
  14. 14         }
  15. 15     }
复制代码
运行验证:体系桌面、应用窗体如VisualStudio以及网页等光标编辑状态,都乐成隐藏
还原光标状态:
  1. 1     private void ShowCursor()
  2. 2     {
  3. 3         for (int i = 0; i < _systemCursorIds.Length; i++)
  4. 4         {
  5. 5             SetSystemCursor(_previousCursorHandles[i], (uint)_systemCursorIds[i]);
  6. 6         }
  7. 7     }
复制代码
用到的User32及参数类:
  1. 1    [DllImport("user32.dll", SetLastError = true)]
  2. 2    public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
  3. 3    [DllImport("user32.dll")]
  4. 4    public static extern IntPtr CopyIcon(IntPtr cusorId);
  5. 5    [DllImport("user32.dll")]
  6. 6    public static extern IntPtr LoadCursorFromFile(string lpFileName);
  7. 7    [DllImport("user32.dll")]
  8. 8    public static extern bool SetSystemCursor(IntPtr hcur, uint id);
  9. 9    [DllImport("user32.dll")]
  10. 10    static extern bool GetCursorInfo(out CURSORINFO pci);
  11. 11
  12. 12    [StructLayout(LayoutKind.Sequential)]
  13. 13    public struct POINT
  14. 14    {
  15. 15        public Int32 x;
  16. 16        public Int32 y;
  17. 17    }
  18. 18
  19. 19    [StructLayout(LayoutKind.Sequential)]
  20. 20    public struct CURSORINFO
  21. 21    {
  22. 22        public Int32 cbSize;        // Specifies the size, in bytes, of the structure.
  23. 23                                    // The caller must set this to Marshal.SizeOf(typeof(CURSORINFO)).
  24. 24        public Int32 flags;         // Specifies the cursor state. This parameter can be one of the following values:
  25. 25                                    //    0             The cursor is hidden.
  26. 26                                    //    CURSOR_SHOWING    The cursor is showing.
  27. 27        public IntPtr hCursor;          // Handle to the cursor.
  28. 28        public POINT ptScreenPos;       // A POINT structure that receives the screen coordinates of the cursor.
  29. 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体系光标显示
出处:http://www.cnblogs.com/kybs0/本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表