Blog. Just Blog

Как узнать установленный в системе масштаб текста

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Как узнать установленный в системе масштаб текста
Как узнать установленный в системе масштаб текста

Технический прогресс неумолимо наступает, разрешение мониторов с каждым годом становится все больше. В результате пользователям приходится увеличивать масштаб, чтобы не ломать глаза разглядыванием микрошрифта. И если программа изначально написана под "стандартный" DPI=96, то при отображении на мониторе с бОльшим значением DPI некоторые элементы ее интерфейса скорее всего будут отображаться некорректно. Это приходится учитывать разработчикам при написании своих программ. По возможности я тоже начал обновлять свои утилиты, чтобы в них учитывался установленный в системе масштаб текста. Естественно, что для этого потребовались определенные инструменты.

Самый простой способ узнать установленный масштаб текста - прочитать его из реестра. Текущее значение записано в параметре AppliedDPI ключа HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics Дефолтному масштабу соответствует значение 96, для среднего оно будет 120 и для крупного - 144. В бесятке вроде бы есть масштаб 200%, для него значение DPI 192. Других значений не предусмотрено, по крайней мере я их пока не встречал.
  1. ;---------------------------------------------------------
  2. ; Функция получения установленного значения DPI
  3. ;---------------------------------------------------------
  4. ; На выходе:
  5. ;   EAX = установленное значение
  6. ;---------------------------------------------------------
  7. proc GetDPI
  8.         locals
  9.           phkResult  dd ?
  10.           lpdwDisp   dd ?
  11.           bufferSize dd ?
  12.           result     dd ?
  13.         endl
  14.  
  15.         pusha
  16.  
  17.         ; На всякий случай дефолтное значение
  18.         mov     [result],96
  19.  
  20.         ; Прочитать значение из реестра
  21.         KEY_WOW64_64KEY = 0x100
  22.         lea     eax,[phkResult]
  23.         push    eax
  24.         invoke  RegOpenKeyEx,HKEY_CURRENT_USER,.reg,NULL,\
  25.                 KEY_QUERY_VALUE+KEY_WOW64_64KEY
  26.         jnz     .loc_exit
  27.         mov     [bufferSize],4
  28.         mov     [lpdwDisp],REG_DWORD
  29.         lea     eax,[bufferSize]
  30.         push    eax
  31.         lea     eax,[result]
  32.         push    eax
  33.         lea     eax,[lpdwDisp]
  34.         push    eax
  35.         invoke  RegQueryValueEx,[phkResult],.key,0
  36.         invoke  RegCloseKey,[phkResult]
  37. .loc_exit:
  38.         mov     eax,[result]
  39.         mov     [esp+28],eax
  40.         popa
  41.         ret
  42.  
  43. align 4
  44. .reg    db 'Control Panel\Desktop\WindowMetrics',0
  45. align 4
  46. .key    db 'AppliedDPI',0
  47. endp
Также обратите внимание, что текстовые строки тут обязательно надо выравнивать на границу DWORD, иначе функции работы с реестром могут завершиться с ошибкой, особенно при работе с юникодом.

Но просто получить значение DPI недостаточно, с его помощью надо будет пересчитывать различные параметры элементов диалогового окна. Для этого я нарисовал вот такую вспомогательную функцию.
  1. ;---------------------------------------------------------
  2. ; Функция пересчета чисел на основании значения DPI
  3. ;---------------------------------------------------------
  4. ; На входе:
  5. ;   dDPI - значение DPI, под которое нужно пересчитать
  6. ;   dValue - пересчитываемое число
  7. ; На выходе:
  8. ;   EAX = пересчитанное число
  9. ;---------------------------------------------------------
  10. proc ScaleDPI dDPI:DWORD,dValue:DWORD
  11.         pusha
  12.         mov     eax,[dValue]
  13.         mov     ecx,[dDPI]
  14.         ; Дефолтное DPI, ничего не конвертируем
  15.         cmp     ecx,96
  16.         je      .loc_ret
  17.         ; NewValue = OldValue * DPI / 96
  18.         xor     edx,edx
  19.         mul     ecx
  20.         mov     ecx,96
  21.         div     ecx
  22. .loc_ret:
  23.         mov     [esp+28],eax
  24.         popa
  25.         ret
  26. endp
На входе передаем значение DPI и исходное число, которое надо пересчитать с желаемым коэффициентом, на выходе получаем пересчитанное значение.

В приложении пример программы с исходником, которая определяет и выводит установленный в системе масштаб текста.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Get.Current.DPI.Demo.zip (2,058 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 552 | Комментариев: 3

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
LonerD (30.05.2023 в 00:22):
В десятке стандартные масштабы
100-125-150-175-200-225 %
Соответственно DPI для них
96-120-144-168-192-216

А в целом в десятке можно ставить от 100% до 500% любое DPI
К примеру, при 140% значение будет 134.
ManHunter (14.04.2023 в 14:15):
*непереводимая игра слов, с использованием местных идиоматических выражений*
Тут поправил, в программах тоже поправил, где успел добавить. Спасибо!
Александр (14.04.2023 в 14:04):
Ага, теперь понятно как вы определяете DPI в программе "Friendly Password Generator", у меня в "wine" версия 1.8 открывается с огромным масштабом символов в верхнем поле вообще пусто, а в нижнем помещаются 2,5 символа без прокрутки, оказалось в реестре "wine" нет ключа "AppliedDPI", после его добавления масштаб в программе корректный.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0048 сек.) / Память: 4.5 Mb
Наверх