Dpi aware что это
Высокие значения DPI в ОС Windows
Windows, начиная с Vista, предоставляет два механизма для адаптации приложений к мониторам с высокой плотностью пикселей (точек на дюйм, DPI): увеличенные системные шрифты и полномасштабное увеличение окон. К сожалению, попытка заставить некоторые ваши приложения работать в каком либо из режимов может оказаться безуспешной, благодаря сочетанию нерадивых разработчиков и плохих решений принятых Microsoft.
От переводчика
Методы масштабирования
Чтобы исправить ситуацию, Microsoft решила, что неплохо встроить какой-нибудь метод масштабирование в Windows. Один из двух методов описанных ниже (Windows XP или Vista), применяется когда пользователь устанавливает DPI со значением выше чем стандартные 96 точек на дюйм. Оба метода пытаются увеличить размер элементов изображения.
Масштабирование в стиле Windows XP
Первый из этих методов, как можно догадаться, появился в Windows XP. Этот метод, на самом деле, не является методом масштабирования приложений с графическим интерфейсом как таковой. Масштабируются, при более высоких настройках DPI, только системные шрифты и некоторые элементы пользовательского интерфейса системы (я бы назвал его «метод НЕ масштабирования» в стиле Windows XP).
Все остальные элементы приложений по-прежнему отображаются в масштабе 1:1. Единственной разницей в их внешнем виде является то, что любой текст и некоторые элементы GUI, выводимые с помощью системных функций, вдруг становиться больше. Например, текст на кнопках. Это вызывает очевидные проблемы которые мы обсудим чуть позже.
Масштабирование в стиле Windows Vista или DPI виртуализация
Windows Vista представила второй вариант со странным названием, «масштабирование дисплея», без каких-либо уточнений, видимо, чтобы окончательно запутать пользователей. Мы будем использовать более описательное имя – метод DPI виртуализации. Когда этот метод включен, Windows по-прежнему выполняет масштабирование в стиле Windows XP. Также как и прежде размеры всех системных шрифтов и некоторых элементов интерфейса системы увеличиваются.
Разница в том, что приложения, которые могут правильно использовать высокие значения DPI, должны сообщить об этом Windows. Такие приложения должны установить новый DPI-Aware флаг, либо путем вызова функции Win32 API «SetProcessDPIAware», или, предпочтительно, путем встраивания манифеста с флагом dpiAware. А вот если у приложения отсутствует DPI-Aware флаг, Windows ведет себя по другому, сначала она формирует внутреннее отображение в масштабе 96 точек на дюйм (эмулируя для приложения DPI равный 96), а затем, масштабирует полученное изображение в соответствие с текущими настройками DPI перед выводом на экран.
Это было бы фантастическим метод масштабирования если бы все наши мониторы имели плотность пикселей последних аппаратов iPhones (326 точек на дюйм). К сожалению это не так. Окна приложений масштабированные таким образом выглядят чересчур размыто, при популярном разрешении 120 точек на дюйм (@homm это не разрешение, кстати). Поэтому, Microsoft по умолчанию отключает DPI виртуализацию, если вы выберете плотность пикселей меньше или равную 120 DPI.
Как изменить установки DPI
В Windows 7/8, откройте «Панель управления», a затем выберите «Оформление и персонализация», затем «Экран», и, наконец, выберите «Установить размер шрифта (DPI)» (Windows 7) или «Пользовательские параметры размера» (Windows 8). Вы увидите следующее диалоговое окно (Windows 7, в Windows 8 почти идентично):
В раскрывающимся списке можно выбрать нужную настройку DPI в процентном соотношении, где 100% соответствует 96 DPI, 125% — как на скриншоте, соответствует 120 точкам на дюйм (можно более точно записать значение вручную). До Windows 8 фактическое значение DPI («пикселей на дюйм») отображалось рядом с размером системного шрифта. Windows 8, по непонятным причинам, не показывает значение DPI, так что вы должны рассчитать его самостоятельно.
Также вы можете приложить линейку (у которой есть шкала в дюймах) к экрану, и пытаться совместить маркировку на ней с маркировкой на экране, изменяя значение в раскрывающимся списке. Флажок, обведенный красным внизу, определяет, следует ли использовать только масштабирование в стиле Windows XP, или также новый способ DPI виртуализации. Если флажок не отмечен, как на скриншоте, то DPI виртуализация включена.
Декламация. Это диалоговое окно пример интерфейса не дружественного к пользователю. На первый взгляд кажется, что это флажок для отключения масштабирования в стиле Windows XP. Но этот метод масштабирования (который только увеличивает системные шрифты и другие элементы пользовательского интерфейса системы — масштабирование Windows XP) всегда включается при выборе высокого значения DPI. На самом деле этот флажок управляет, будет ли этот метод единственным (Использовать только масштабы в стиле Windows XP), или также будет применен метод «DPI виртуализации» для приложений, которые не имеют DPI-Aware флага. Так что этот флажок не контролирует метод масштабирования указанный в его название, а контролирует другой метод масштабирования, нигде не упомянутый — и позволяет использовать новый метод, когда флажок снят!
Ошибка в Windows 8. В дополнение к этому, в Windows 8 это диалоговое окно с ошибкой. Как правило, все работает как и в Windows 7, но состояние флажка не сохраняется на значениях DPI 150% и выше. Когда вы устанавливаете этот флажок, «DPI виртуализация» правильно отключается. Тем не менее, сам флажок остается не отмеченным, когда вы в следующий раз открываете этот диалог.
Изменения в Windows 8.1, или почему все размыто?
В Windows 8.1 флажок для масштабирования в стиле Windows XP исчез, и теперь «DPI виртуализация» никогда, не используется при значениях DPI до 120 включительно, но всегда используется при более высоких значениях для тех программ, у которых отсутствует DPI-Aware флаг. Если некоторые приложения кажутся вам нечеткими, необходимо вручную отключить для них DPI виртуализацию.
Windows 8.1 позволяет использовать несколько мониторов с разным значением DPI. Однако эта функция, также заставляет использовать «DPI виртуализацию» для традиционных приложений, которые перемещаются между мониторами с разными значениями DPI. Чтобы этого избежать, можно отключить в настройках «DPI масштабирование», используя новую опцию «Я хочу выбрать один масштаб для всех дисплеев».
Также Windows 8.1 добавляет специальный переключатель для настройки 200% и новый API, чтобы разработчики могли выборочно отключать «DPI виртуализацию».
Помогите, мои системные шрифты не правильного размера!
Иногда, после изменения настроек DPI, вы можете заметить что некоторые системные шрифты стали слишком большими или слишком маленькими для новых установок. Вероятной причиной является то, что вы используете пользовательскую тему рабочего стола на основе ваших старых настроек DPI. Windows не масштабирует шрифты пользовательской темы.
Если вы на самом деле создали пользовательскую тему рабочего стола и хотите сохранить её, вам придется самостоятельно адаптировать шрифты к новым настройкам DPI. Однако, Windows имеет раздражающую привычку «услужливо» создавать пользовательские темы без вашего ведома, по какой-либо причине. Так что, если вы никогда не создавали пользовательскую тему рабочего стола просто удалите её и вернитесь к стандартной теме.
В Windows 7/8, откройте Панель управления, выберите «Оформление и персонализация», а затем «Персонализация». Если вы видите выбранную запись в строке «Мои темы», это означает, что ОС Windows использует тему пользователя, системные шрифты которой Windows не будет масштабировать. Выберите стандартную тему, например, первую запись в разделе «Темы Aero» (Windows 7) или «Windows» «Темы по умолчанию» (Windows 8) и удалите нежелательные записи в разделе «Мои темы». Теперь, все системные шрифты должны отображаться правильно.
Типы приложений, как они масштабируются (или не масштабируются)
Теперь давайте рассмотрим какие методы должны использоваться для существующих Windows приложений при высоких значениях DPI. Следующая таблица обобщающая, позже мы рассмотрим различные случаи более подробно.
DPI-Aware флаг не установлен | DPI-Aware флаг установлен | |
Не DPI-Aware | Нужно использовать DPI виртуализацию | Нужны исправления от разработчиков |
DPI-Aware | Нужно использовать масштабирование в стиле Windows XP | Всегда масштабируется правильно |
Приложения вообще не заботящиеся о DPI — это либо очень старые или плохо написанные, но, тем не менее, по-прежнему используемые. Одним известным примером является ITunes от Apple для Windows. Здесь разработчики используют системные шрифты для GUI и, не заботясь о фактических размерах шрифта, они жестко привязывают размеры окон к разрешению 96 DPI, естественно искажая GUI, когда при более высоких значениях DPI увеличиваются размеры шрифтов.
Такие приложения требуют нового метод масштабирования «виртуализации DPI», к сожалению, это часто делает интерфейс размытым. В противном случае вы столкнетесь с проблемами начиная, от обрезания текста до перекрытия элементов контроля, иногда, делая GUI полностью непригодным (к счастью, это, случается редко). За эти годы я собрал несколько образцов скриншотов не корректных приложений.
разрешение 150% (144 DPI)
Приложения умеющие подстраивать свой GUI под различные значения DPI, имеющие DPI-Aware флаг — Это новейший тип приложений которые полностью беспроблемны, независимо от настроек DPI. DPI-Aware флаг установлен автоматически для Windows Presentation Foundation (WPF) и GDI+ приложений, так как эти APIs предоставляют встроенные средства масштабирования. Разработчикам использующим старый GDI API и (удивительно) Windows Forms, нужно вручную помечать свои DPI-Aware приложения.
Приложения не приспособленные к изменению DPI, но имеющие DPI-Aware флаг — это еще хуже чем полностью игнорирование значения DPI. В примерах вы найдете GUI приложений, хорошо масштабируемых вплоть до 120 DPI, но не выше, или приложений JavaFX. Тут мы уже ничего сделать не можем, т.к. у нас нет возможности заставить Windows использовать DPI виртуализацию, для таких программ. После того как DPI-Aware флаг установлен, приложение должно масштабировать себя самостоятельно. Мы можем только «пилить» разработчиков исправить их продукт — или использовать что-то другое.
Выбор метода масштабирования для ваших приложений
После того как вы решили что вы хотите использовать высокое значение DPI, ваш выбор метода масштабирования зависит от приложений в которых вы работаете. Имейте в виду, что, отключить «DPI виртуализацию» означает, установить флажок (check box) с некорректным названием «Использовать масштабы в стиле Windows XP» и наоборот.
Напоминаем, что в Windows 8.1 уже нет возможности выбора в этом вопросе. Если вы работаете при разрешении в 120 точек на дюйм (125%), каждая программа будет вынуждена использовать масштабирование в стиле Windows XP, a если вы работаете с более высоким разрешением, каждая программа, которая не является DPI-Aware, будет использовать по умолчанию «DPI виртуализацию».
Отказ от DPI виртуализации для отдельных приложений
После того как вы решили включить DPI виртуализацию или вы работаете в Windows 8.1, с разрешением более чем 120 точек на дюйм, вы можете проверить систему на предмет наличия DPI-Aware приложений, которые не имеют соответствующий флаг. И вернуть им возможность использовать масштабирование в стиле Windows XP, для которого они предназначены. Есть два способа сделать это, первый работает только для 32-разрядных приложений, второй универсален и подходит также для 64-битных приложений.
32-разрядные приложения — Это просто: щелкните правой кнопкой мыши на исполняемом файле в Проводнике Windows, выберите диалоговое окно «Свойства», перейдите на вкладку «Совместимость» и установите флажок «Отключить масштабирование изображения при высоком разрешении экрана». Вот и все, в Windows 8.1 это также работает для 64-битных приложений.
64-разрядные приложения — Без всякой видимой причины, возможно чтобы позлить пользователей 64-битных приложений, в Windows 8 и более ранних, упомянутый выше флажок, для 64-разрядных приложений отключен, хотя сам вариант вполне функционален, если внести изменения непосредственно реестр! Так что, запустите редактор реестра и перейдите к этому ключу:
Теперь добавьте строковое значение (REG_SZ), чье имя является полным путем к исполняемому файлу приложения и значением которого является HIGHDPIAWARE. Я рекомендую, чтобы вы сначала изменили несколько 32-битных приложений, как описано выше, чтобы вы могли увидеть некоторые примеры значений в этом ключе реестра.
Мы рассмотрели, как можно использовать настройки DPI на Windows Vista и более поздних версиях. И если вы когда-нибудь задумывались, для чего предназначена опция совместимости — «Отключить масштабирование изображения при высоком разрешении экрана». И почему она ничего не делает на вашей системе, теперь вы знаете: она эффективна, только если у вас включена общесистемная опция «DPI виртуализации» и только для приложений, которые не устанавливают DPI-Aware флаг должным образом, но при этом корректно используют масштабирование в стиле Windows XP.
Дальнейшее чтение
For more information about both scaling methods from a developer perspective, see the MSDN article Writing High-DPI Win32 Applications. This content has moved to Writing DPI-Aware Desktop and Win32 Applications. This lengthy article also contains a sample manifest to declare an application as DPI-aware, as well as sample screenshots for the various scaling methods and tips on display scaling in native code.
Unfortunately, the article currently only covers Windows XP through 7. See Writing DPI-Aware Desktop Applications in Windows 8.1 Preview (Word DOCX) and Chuck Walbourn’s Manifest Madness for additional information on Windows 8 and 8.1.
Outside of Microsoft, Gastón Hillar has published two articles targeting Windows 8.1 at Dr. Dobb’s. Part 1 covers basic concepts, and part 2 shows C/C++ sample code for the Win32 API.
Зачем DPI aware портит нам жизнь?
Вот кстати не пойму, накой надо было уменьшать пикселы, неужели кому-то они казались слишком большими?
Интересно, они уже починили отот баг, когда ты через SetCursorPos ставишь курсор в одно место (в центр), а он из-за всех этих dpi преобразований оказывается в другом (плюс/минус один пиксель), из-за чего игры, в которых мышь обрабатывается через Set(Get)CursorPos, сломалось (камера начинает крутиться).
nes
> Вот кстати не пойму, накой надо было уменьшать пикселы, неужели кому-то они
> казались слишком большими?
а) они были слишком большие.
б) как бы никогда у пикселя небыло прям вот чёткого размера на всех мониторах, просто раньше разница в десктоп сегменте была не в разы.
>б) как бы никогда у пикселя небыло прям вот чёткого размера на всех мониторах, просто раньше разница в десктоп сегменте была не в разы.
Вроде как он был примерно одинаковым на всех старых мониторах и равнялся примерно 96 pixels / inch.
nes
> Вроде как он был примерно одинаковым на всех старых мониторах и равнялся
> примерно 96 pixels / inch.
или 72 пикселя/дюйм? 🙂
ну ты сам должен понимать что 1024х768 на 14 дюймах и на 17 дюймах это разные вещи. Это конечно не фуллхд или 4к на 24 дюймах, но всё равно разница была и была ощутима.
SuperInoy
Ну вот мне на работе выдали 24 дюймовый монитор с разрешением 3840×2160,
но на нем не реально работать, если не поставить скейлинг 150% (который как не удивительно является рекомендуемой настройкой в системе).
Ну вот на кой хрен мне столько пикселов тут?
nes
> Ну вот на кой хрен мне столько пикселов тут?
чтобы в пейнте на линии в 1 пиксель не видеть лесенку.
nes
> Ну вот мне на работе выдали 24 дюймовый монитор с разрешением 3840×2160,
Объясни им что тебе неудобно, фуллхд моник за 8к тебе вероятно вместо него выдадут 🙂
122
Галочка не спасет ровно никак.
Поставь ее, запусти приложение, затем поменяй в системе DPI скейлинг,
окно измет размер.
122
Короче работает павильно, если вызвать функцию:
nes
> Кто-то свыше решил, что теперь разработчик должен программировать гуйню в
> дюймах и переводить в пикселы (которыми оперируют функции системного апи)
> вручную.
В общем-то не кто-то свыше, а просто внедрили типографские стандарты в отображение текстовой информации на компьютерной технике. Просто у Windows, изначально не всё было хорошо с этим делом и старые нехорошие API до сих пор не выпилили. А вот MacOS X изначально пилилась под типографские стандарты и там нет таких проблем (но это не точно).
nes
> Короче работает павильно, если вызвать функцию:
>
> SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
> А это чудо доступно только в windows 10.
А в вин ниже 10 делай пиксель пёрфект без масштабирования. Ибо нефиг сидеть на говне мамонта и при этом покупать 8к мониторы.
SuperInoy
Некоторые утверждают, что семерка лучше десятки, но это уже отдельная тема для холивара.
nes
> Некоторые утверждают, что семерка лучше десятки, но это уже отдельная тема для
> холивара.
Ну я так утверждаю, но накатывать 7-ку на свежее железо всё равно не вижу смысла. А на не свежем будет фуллхд/2к с соответствующей диагональю(за исключением некоторых ноутов с хайдпи экранами)
Поддержка определения DPI в Windows 10: как посмотреть, какие проги как отображаются
С выходом Windows 10 May 2019 Update у Диспетчера задач Windows 10 официально появилась еще одна дополнительная колонка. Называется она «Поддержка определения DPI».
То есть диспетчер теперь показывает, какие из установленных на компе приложений поддерживают определение DPI. Что это и зачем?
Ну, для начала напомним, что параметр «dots per inch» или сокращенно DPI обозначает количество (плотность) пикселей на физической единице площади панели экрана.
Стандартно компьютерные мониторы оснащались панелями, у которых на физический дюйм площади приходилось 96 пикселей. Но по мере развития технологий у производителей появилась возможность увеличивать плотность пикселей на дюйм, в итоге сейчас в рознице можно сравнительно недорого купить мониторы с панелями на 200 DPI и даже больше.
Однако тут же пришлось бороться с одной проблемкой. Дело в том, что при более высоком значении DPI картинка на экране монитора в целом получается более четкой, но и масштабировать её приходится по-новому, иначе все визуальные элементы и тексты становятся очень маленькими и читать/юзать их гораздо сложнее.
Проблему эту разработчики софта, само собой, начали решать. Поэтому все новые приложения Windows 10 из Microsoft Store умеют автоматом подстраиваться под значение DPI монитора.
А вот со старыми — все не так просто. И до сих пор есть уйма полезных прог, которые изначально разрабатывались под стандарты Win32, самомасштабироваться не обучены и на современных мониторах с высоким DPI отображаются либо с размытыми текстами, либо с кривыми иконками и боксами, либо… в общем, плохо отображаются.
Поэтому чтобы пользователям Windows 10 проще было выявлять те приложения, у которых могут быть проблемы с масштабированием, в Microsoft придумали показывать такие проги в Диспетчере задач системы.
Фича эта (в оригинале называется она DPI Awareness) тестировалась еще с прошлого года, а с майским обновлением теперь в Windows 10 (v.1903) присутствует официально, как мы уже сказали, в виде отдельной колонки «Поддержка определения DPI» в окне Диспетчера.
как посмотреть, какие из приложений на компе поддерживают определение DPI
Собственно, на этом можно было и закончить. Однако, наверняка, не лишним будет вкратце описать и те значения, которые отображаются в столбце «Поддержка определения DPI«. Ибо их несколько, для разных приложений — разные режимы. А именно:
PROCESS_DPI_AWARENESS enumeration (shellscalingapi.h)
Identifies dots per inch (dpi) awareness values. DPI awareness indicates how much scaling work an application performs for DPI versus how much is done by the system.
Users have the ability to set the DPI scale factor on their displays independent of each other. Some legacy applications are not able to adjust their scaling for multiple DPI settings. In order for users to use these applications without content appearing too large or small on displays, Windows can apply DPI virtualization to an application, causing it to be automatically scaled by the system to match the DPI of the current display. The PROCESS_DPI_AWARENESS value indicates what level of scaling your application handles on its own and how much is provided by Windows. Keep in mind that applications scaled by the system may appear blurry and will read virtualized data about the monitor to maintain compatibility.
Syntax
Constants
В |
---|
PROCESS_DPI_UNAWARE DPI unaware. This app does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI). It will be automatically scaled by the system on any other DPI setting. |
PROCESS_SYSTEM_DPI_AWARE System DPI aware. This app does not scale for DPI changes. It will query for the DPI once and use that value for the lifetime of the app. If the DPI changes, the app will not adjust to the new DPI value. It will be automatically scaled up or down by the system when the DPI changes from the system value. |
PROCESS_PER_MONITOR_DPI_AWARE Per monitor DPI aware. This app checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes. These applications are not automatically scaled by the system. |
Remarks
Previous versions of Windows required you to set the DPI awareness for the entire application. Now the DPI awareness is tied to individual threads, processes, or windows. This means that the DPI awareness can change while the app is running and that multiple windows can have their own independent DPI awareness values. See DPI_AWARENESS for more information about how DPI awareness currently works. The recommendations below about setting the DPI awareness in the application manifest are still supported, but the current recommendation is to use the DPI_AWARENESS_CONTEXT.
If your app is PROCESS_DPI_UNAWARE, there is no need to set any value in the application manifest. PROCESS_DPI_UNAWARE is the default value for apps unless another value is specified.
In previous versions of Windows, there was no setting for PROCESS_PER_MONITOR_DPI_AWARE. Apps were either DPI unaware or DPI aware. Legacy applications that were classified as DPI aware before WindowsВ 8.1 are considered to have a PROCESS_DPI_AWARENESS setting of PROCESS_SYSTEM_DPI_AWARE in current versions of Windows.
An application that is PROCESS_DPI_UNAWARE will always use a scaling factor of 100% (96 DPI). In this scenario, a PROCESS_DPI_UNAWARE window is created with a size of 500 by 500. On display A, it will render natively with no scaling. On displays B and C, it will be scaled up by the system automatically by a factor of 2 and 3 respectively. This is because a PROCESS_DPI_UNAWARE always assumes a DPI of 96, and the system accounts for that. If the app queries for window size, it will always get a value of 500 by 500 regardless of what display it is in. If this app were to ask for the DPI of any of the three monitors, it will receive 96.
Now consider an application that is PROCESS_SYSTEM_DPI_AWARE. Remember that in the sample, the system DPI is 200% or 192 DPI. This means that any windows created by this app will render natively on display B. It the window moves to display A, it will automatically be scaled down by a factor of 2. This is because a PROCESS_SYSTEM_DPI_AWARE app in this scenario assumes that the DPI will always be 192. It queries for the DPI on startup, and then never changes it. The system accommodates this by automatically scaling down when moving to display A. Likewise, if the window moves to display C, the system will automatically scale up by a factor of 1.5. If the app queries for window size, it will always get the same value, similar to PROCESS_DPI_UNAWARE. If it asks for the DPI of any of the three monitors, it will receive 192.
Unlike the other awareness values, PROCESS_PER_MONITOR_DPI_AWARE should adapt to the display that it is on. This means that it is always rendered natively and is never scaled by the system. The responsibility is on the app to adjust the scale factor when receiving the WM_DPICHANGED message. Part of this message includes a suggested rect for the window. This suggestion is the current window scaled from the old DPI value to the new DPI value. For example, a window that is 500 by 500 on display A and moved to display B will receive a suggested window rect that is 1000 by 1000. If that same window is moved to display C, the suggested window rect attached to WM_DPICHANGED will be 1500 by 1500. Furthermore, when this app queries for the window size, it will always get the actual native value. Likewise, if it asks for the DPI of any of the three monitors, it will receive 96, 192, and 288 respectively.
Because of DPI virtualization, if one application queries another with a different awareness level for DPI-dependent information, the system will automatically scale values to match the awareness level of the caller. One example of this is if you call GetWindowRect and pass in a window created by another application. Using the situation described above, assume that a PROCESS_DPI_UNAWARE app created a 500 by 500 window on display C. If you query for the window rect from a different application, the size of the rect will vary based upon the DPI awareness of your app.
В
Examples
This snippet demonstrates how to set a value of PROCESS_SYSTEM_DPI_AWARE in your application manifest.
This snippet demonstrates how to set a value of PROCESS_PER_MONITOR_DPI_AWARE in your application manifest.