Преобразование HIMETRIC в пиксели в среде с несколькими DPI - PullRequest
0 голосов
/ 17 октября 2018

Моя структура пользовательского интерфейса использует двойные значения для координат пикселей, что дает мне хорошие дробные виртуальные координаты на дисплеях сетчатки.Для этого я получаю координаты мыши из Windows в единицах HIMETRIC.Однако я столкнулся с ошибкой, которую не могу выяснить.

У меня Surface Book 2 (3000x2000 @ 225%) подключен к док-станции с двумя внешними мониторами (1920x1080 @ 100%).Если я вхожу в Windows с подключенной док-станцией (и внешний монитор @ 100% установлен в качестве основного), я получаю правильные координаты HIMETRIC, которые работают как на внешнем дисплее, так и на сетчатке.

Однако, если я войду в Windows, когда док-станция отключена, значит, только монитор сетчатки, затем подключите док-станцию ​​и запустите мое приложение - теперь оно получает HIMETRIC-координаты , масштабированный по коэффициенту масштабирования дисплея, который был основным , когда я вошел в Windows .

Я установил для DPI моего приложения осведомленность о PerMonitorV2, поэтому я нахожу егонастолько странно, что настройка масштаба для каждой системы имеет отношение даже к моему приложению.

Это функция, которую я использую для преобразования из HIMETRIC:

double fromHimetric(uint i)
{
    return (double)i / 2540 * Monitor::DefaultDPI; 
}

Monitor::DefaultDPI - это константа, равная 96.

Я что-то упустил?Нужно ли добавлять в формулу коэффициент масштабирования системы?В таком случае, как я могу узнать, какой монитор был основным при входе в Windows?Потому что это, кажется, остается неизменным независимо от того, на какой монитор я перемещаю свое окно, поскольку я получаю значения HIMETRIC, которые, по-видимому, масштабируются на значения из прошлого.

Редактировать: , потому чтоВ интернете сложно описать материал монитора. Я снял небольшое видео, показывающее, как эта ошибка проявляется для меня.https://www.youtube.com/watch?v=pTZiTZFXsc0

Редактировать 2: Просто чтобы прояснить это еще раз, мое приложение полностью учитывает DPI для каждого монитора, весь мой пользовательский интерфейс настроен так, что он масштабируется правильно, я обрабатываю WM_DISPLAYCHANGE и WM_DPICHANGED, все такое.Координаты пера и касания работают хорошо во всех случаях.

Единственное, что нарушает , если я первоначально запускаю свой компьютер без отсоединения , это то, что HIMETRIC-координаты, которые я получаю для мыши из GetPointerInfo(), масштабируются дисплееммасштаб монитора, который был основным при запуске компьютера.

Я усердно работал, чтобы убедиться, что я справляюсь с ситуациями с несколькими мониторами и многими DPI.Я буду чувствовать себя очень глупо, если есть одна простая вещь, которую я упустил из виду, которая ломает все.

Редактировать 3: Посмотрите, насколько велики полосы прокрутки в Chrome.https://imgur.com/a/F3dFHAj

Или студия OBS: https://imgur.com/a/11aG5Kw

Кажется, они страдают от подобных ошибок.Не знаю, имеют ли они какое-либо отношение к HIMETRIC, но эти элементы отображаются по-разному в зависимости от того, как я запускаю компьютер.

Определяет ли Win32 что-то вроде монитора запуска ?

Редактировать 4: Причина, по которой я не использую AtlHiMetricToPixel() и PhysicalToLogicalPoint()в том, что они возвращают целочисленные логические координаты, и я специально хочу удваивать в логическом пространстве, так как весь мой интерфейс основан на векторах.Я делаю все масштабирование самостоятельно, и это, кажется, работает хорошо, за исключением этого случая.(

...