Извлечь размер курсора через WinAPI (Windows 10) - PullRequest
1 голос
/ 06 августа 2020

Мне нужно извлечь изображение курсора, чтобы использовать его в моем приложении Swing (Java).

Во-первых, я нашел аналогичный вопрос , измененный фрагмент кода из ответа и получил это приложение-песочницу .

Вскоре он получает изображение курсора через JNA и WinAPI, затем показывает это изображение в JFrame и устанавливает собственный курсор для этого кадра.

В большинстве случаев случаях этот код работает корректно и подходит для моих задач. Но затем я обнаружил, что , когда пользователь изменяет размер или цвет курсора (Windows 10 функция ), программа извлекает недопустимое изображение курсора, которое не соответствует исходному курсору ни по цвету, ни по по размеру.

Когда у пользователя стандартный курсор:

enter image description here

When the user has e.g. pink cursor then bigger than standard one:

enter image description here

After this situation, I decided to do the same sandbox application, but via C++ and WinAPI. I used answers for this вопрос , но решались только проблемы с цветом.

enter image description here

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 здесь , но я не уверен.

Итак, мой вопрос:

Как я могу получить реальный размер курсора?

Заранее большое спасибо!

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Я думаю, что основным узким местом является то, что функция GetSystemMetrics возвращает размер курсора по умолчанию (32x32), и он не меняется после изменения размера курсора.

Когда пользователь изменяет размер курсора через Настройки . Системные настройки обновят это изменение до значения реестра CursorBaseSize в HKEY_CURRENT_USER\Control Panel\Cursors.

Вы можете получить уведомление, когда произойдет изменение, через WM_SETTINGCHANGE или SetWinEventHook (EVENT_OBJECT_SHOW, OBJID_CURSOR).

Затем прочтите значение регистра CursorBaseSize, чтобы получить новый размер и получить другую информацию, используя GetIconInfoEx для создания курсора указанного размера. (CreateCursor)

Дополнительные ссылки: Как я могу получить уведомление при изменении курсора?

0 голосов
/ 19 августа 2020

Спасибо @Rita Han - MSFT за указание начальной точки для начала поиска.

Вы можете получить реальный размер курсора двумя способами:

  1. Первый способ упомянут ранее : нам нужно получить значение из значения реестра CursorBaseSize под HKEY_CURRENT_USER\Control Panel\Cursors.
  2. Был найден второй способ здесь : мы можем получить множитель размера курсора из значения реестра CursorSize под HKEY_CURRENT_USER\Software\Microsoft\Accessibility, а затем самостоятельно рассчитайте размер курсора. Это можно сделать как-то так: newHeight = cursorHeight + (multiplier - 1) * (cursorHeight / 2);, где cursorHeight - значение из GetSystemMetrics(SM_CYCURSOR), а multiplier - значение из реестра. Значение реальной ширины курсора будет таким же, как newHeight. Все значения равны unsigned long, если мы используем C ++. `

Оба метода нахождения размера приводят к одному и тому же результату.

Если вам нужно найти чтобы получить значение реального размера курсора из реестра в Java, вы можете использовать класс Advapi32Util из JNA-platform:

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