通过WinAPI(Windows 10)提取光标大小

4

我需要提取光标图像以在我的Swing应用程序(Java)中使用。

首先,我找到了类似的问题,从答案中修改了代码片段,并得到了沙盒应用程序

简而言之,它通过JNA和WinAPI获取光标图像,然后在JFrame上显示此图像,并为此框架设置自定义光标。

在大多数情况下,这段代码运行正确并适合我的任务。但是,我发现当用户更改光标的大小或颜色(Windows 10功能)时,程序会提取一个无效的光标图像,既不匹配原始光标的颜色也不匹配大小。

当用户有标准光标时:

enter image description here

当用户有粉色光标时,比标准光标更大:

enter image description here

在这种情况下,我决定使用C++和WinAPI创建相同的沙盒应用程序。我参考了问题的答案,但只解决了颜色方面的问题。

enter image description here

我认为主要瓶颈在于GetSystemMetrics函数返回默认光标大小(32x32),且在光标大小更改后不会改变。我在这里找到了一些证据,但我不确定。
因此我的问题是:
如何获取真实的光标大小?
非常感谢您的帮助!

这回答解决了你的问题吗?如何在VS C ++中获取鼠标光标图标 - Öö Tiib
在我的cpp沙盒中,我做了同样的事情,但它不能处理光标尺寸的更改。光标始终为32x32。 - BaLiK
2个回答

5
我认为主要瓶颈在于GetSystemMetrics函数返回默认光标大小(32x32),并且在光标大小更改后不会更改。当用户通过设置更改光标大小时,系统设置将更新此更改到注册表值CursorBaseSize下的HKEY_CURRENT_USER\Control Panel\Cursors。您可以通过WM_SETTINGCHANGE或SetWinEventHook(EVENT_OBJECT_SHOW,OBJID_CURSOR)获取更改发生时的通知。
然后读取CursorBaseSize寄存器的值以获取新的大小,并使用GetIconInfoEx获取其他信息,创建具有指定大小的光标。(CreateCursor)
更多参考:如何在光标更改时收到通知?

2

感谢 @Rita Han - MSFT 提供起点开始搜索。

有两种方法可以获取真实的光标大小:

  1. 第一种方法已经提到过:我们需要从注册表值 HKEY_CURRENT_USER\Control Panel\Cursors 下的 CursorBaseSize 获取值。
  2. 第二种方法在这里找到:我们可以从注册表值 HKEY_CURRENT_USER\Software\Microsoft\Accessibility 下的 CursorSize 获取光标大小倍增器,然后自己计算光标大小。可以像这样完成:newHeight = cursorHeight + (multiplier - 1) * (cursorHeight / 2); 其中 cursorHeight 是来自 GetSystemMetrics(SM_CYCURSOR) 的值,而 multiplier 则是来自注册表的值。光标的实际宽度值将与 newHeight 相同。如果我们使用C++,所有值都是无符号长整型

两种查找尺寸的方法都会得出相同的结果。

如果您需要在 Java 中从注册表中获取光标实际大小值,则可以使用 JNA-platformAdvapi32Util 类:

        // Read an int (& 0xFFFFFFFFL for large unsigned int)
        int baseSize = Advapi32Util.registryGetIntValue(
                WinReg.HKEY_CURRENT_USER, "Control Panel\\Cursors", "CursorBaseSize");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接