Reputation: 99
I need to extract the cursor image for using it in my swing application (Java).
Firstly, I found similar question, modified code snippet from an answer, and got this sandbox application.
Shortly, it gets cursor image via JNA and WinAPI, then shows this image on JFrame and sets custom cursor for this frame.
In most cases, this code works correctly and suits my tasks. But then I found that when the user changes the cursor's size or color(Windows 10 feature), the program extracts an invalid cursor image that matches the original cursor neither in color nor in size.
When the user has standard cursor:
When the user has e.g. pink cursor then bigger than standard one:
After this situation, I decided to do the same sandbox application, but via C++ and WinAPI. I used answers for this question, but solved only troubles with color.
I think the main bottleneck is that GetSystemMetrics
function returns default cursor size (32x32) and it doesn't change after the cursor's size changing. I found some proves for this here, but I'm not sure.
So my question is:
How can I get the real size of cursor?
Thanks a lot in advance!
Upvotes: 4
Views: 1757
Reputation: 99
Thanks @Rita Han - MSFT for giving the initial point to start searching.
You can get a real cursor size in two ways:
CursorBaseSize
under HKEY_CURRENT_USER\Control Panel\Cursors
.CursorSize
under HKEY_CURRENT_USER\Software\Microsoft\Accessibility
and then calculate the cursor size yourself. It can be done somehow like this: newHeight = cursorHeight + (multiplier - 1) * (cursorHeight / 2);
where cursorHeight
is value from GetSystemMetrics(SM_CYCURSOR)
and multiplier
is value from the registry. The cursor real width value will be the same as newHeight
. All values are unsigned long
if we use C++.`Both methods of finding the size lead to the same result.
If you need to find to get cursor real size value from the registry in Java, you can use Advapi32Util
class from JNA-platform
:
// Read an int (& 0xFFFFFFFFL for large unsigned int)
int baseSize = Advapi32Util.registryGetIntValue(
WinReg.HKEY_CURRENT_USER, "Control Panel\\Cursors", "CursorBaseSize");
Upvotes: 2
Reputation: 9700
I think the main bottleneck is that GetSystemMetrics function returns default cursor size (32x32) and it doesn't change after the cursor's size changing.
When user change cursor size via Settings. System Settings will update this change to registry value CursorBaseSize
under HKEY_CURRENT_USER\Control Panel\Cursors
.
You can get notification when change happens via WM_SETTINGCHANGE
or SetWinEventHook
(EVENT_OBJECT_SHOW
, OBJID_CURSOR
).
Then read CursorBaseSize
register value to get new size and get other information using GetIconInfoEx
to creates a cursor having the specified size. (CreateCursor
)
More references: How can I get notified when the cursor changes?
Upvotes: 5