Определение ширины виртуального экрана с использованием нескольких мониторов и разных DPI

Я пытаюсь имитировать ввод мыши, используя SendInput, однако мне нужно определить ширину виртуального экрана в случае наличия нескольких мониторов, чтобы установить dxа также dyзначения, например:

      dx = (x * 65536) / SystemInformation.VirtualScreen.Width;
dy = (y * 65536) / SystemInformation.VirtualScreen.Height;

Проблема в том, что мониторы явно имеют разные значения DPI, что приводит к неправильному виртуальному размеру. Для справки оба SystemInformation.VirtualScreen.Sizeи призывает GetSystemMetrics(SM_CXVIRTUALSCREEN)возвращают те же неверные значения.

я пытался использовать GetSystemMetricsForDPIтоже без успеха.

1 ответ

По умолчанию Windows применяет виртуализацию DPI ко всем координатам.

Если у вас есть 2 дисплея, дополнительный FullHD слева с масштабированием 100% и основной 4k справа с масштабированием 200% DPI, API для настройки экрана сообщит вам, что рабочий стол имеет разрешение 3840x1080 пикселей, а дополнительный — от [-1920 . .. 0], первичный [0 .. 1920]. Чтобы имитировать ввод мыши в центре левого монитора, вы должны использовать координату X -960 * 0x10000 / 1920 = -32768 без флага или 960 * 0x10000 / 3840 = 16384 с флагом.

Вы можете сказать Windows, чтобы она перестала возиться с DPI в вашем приложении, с помощью манифеста.

Если вы сделаете это на том же компьютере, API для конфигурации экрана сообщит вам, что рабочий стол имеет разрешение 5760x2160 пикселей, вторичный такой же, в [-1920 .. 0 ], первичный [ 0 .. 3840 ]. Для отправки ввода мыши в центр левого монитора в этом случае следует использовать координату X -960 * 0x10000 / 3840 = -16384 без флажка или 960 * 0x10000 / 5760 = 10923 с MOUSEEVENTF_VIRTUALDESKфлаг.

Другие вопросы по тегам