Как определить текущее разрешение экрана?

Как мне из Winapi (в C или C++) определить текущее разрешение экрана?

Немного фона:

Я хочу запустить новое полноэкранное окно OpenGL, но хочу, чтобы оно открывалось с тем же размером по горизонтали и вертикали, который уже установлен на рабочем столе. (Теперь, когда все используют ЖК-экраны, я решил, что это лучший способ получить исходное разрешение экрана.)

Мне также не нужно знать глубину цвета рабочего стола, хотя это было бы приятным бонусом.


person Prof. Falken    schedule 07.01.2011    source источник
comment
Пожалуйста, убедитесь, что ваш код может работать с несколькими мониторами каким-то разумным образом.   -  person In silico    schedule 08.01.2011
comment
@ In silico, что такое разумный способ? Запустить игру (это маленькая игра) только на основном мониторе?   -  person Prof. Falken    schedule 08.01.2011
comment
@Amigable Clark Kant: по умолчанию используется основной монитор, но пользователь может установить конкретный монитор на экране настройки в игре. Возможно, также поддерживается mygame.exe /Monitor1 и т. д. И если вы также поддерживаете оконный режим, используйте MonitorFromWindow, чтобы узнать, куда восстанавливать, если они вернутся в полноэкранный режим.   -  person Anders    schedule 08.01.2011
comment
@Amigable Кларк Кант: Андерс в значительной степени ударил по голове тем, что разумно для вашей крошечной игры. Когда я сказал «разумный», я на самом деле имел в виду поведение, соответствующее вашему приложению. В случае с компьютерными играми я должен иметь возможность правильно настроить параметры монитора даже в среде с несколькими мониторами.   -  person In silico    schedule 08.01.2011
comment
@ В силиконе. Но что именно вы хотите? Это будет небольшая двухмерная аркадная игра. Если вы скажете мне, чего вы ожидаете от такого приложения, я могу выслать вам первый релиз, когда он будет готов. :)   -  person Prof. Falken    schedule 08.01.2011
comment
@Amigable Кларк Кант: То, что описал Андерс (см. комментарий выше), в значительной степени соответствует тому, что я ожидаю от вашего приложения. :-)   -  person In silico    schedule 09.01.2011


Ответы (7)


Редактировать: важно помнить, что монитор не всегда «начинается» с 0x0, поэтому просто знать размер недостаточно для позиционирования вашего окна. Вы можете использовать MonitorFromWindow, чтобы найти монитор, на котором находится ваше окно, а затем вызвать GetMonitorInfo.

Если вы хотите пойти по низкоуровневому маршруту или изменить разрешение, вам нужно использовать EnumDisplayDevices, EnumDisplaySettings и ChangeDisplaySettings (это единственный способ получить частоту обновления AFAIK, но GetDeviceCaps сообщит вам глубину цвета)

person Anders    schedule 07.01.2011
comment
Я только что проверил, и GetDeviceCaps работает в настройке multimon, и оба VERT/HORZRES и VREFRESH, похоже, работают, но я смог заставить CreateDC принимать только строку стиля \\.\DISPLAY2, а не \\.\DISPLAY2\Monitor0, поэтому я Я не уверен, что делать, если у одного адаптера более одного монитора, поэтому придерживайтесь EnumDisplaySettings, если вы получили список мониторов из EnumDisplayDevices... - person Anders; 08.01.2011
comment
Я не уверен, как все это применимо при использовании OpenGL в полноэкранном режиме? Такие вещи, как начало с 0x0, это все еще применимо? - person Prof. Falken; 09.01.2011
comment
Вероятно, нет, я говорил об окнах, можно было бы надеяться, что OpenGL абстрагируется от этого, и вы можете просто указать, какой монитор использовать, а он позаботится обо всем остальном. - person Anders; 10.01.2011
comment
@user396483 ... ВИРТУАЛЬНЫЙ ЭКРАН - person Anders; 06.01.2013
comment
GetDeviceCaps, похоже, имеет проблемы с панелями задач в правой или левой части экрана в Windows 7. Мне не удалось обойти эту проблему ... возможно, придется использовать другой подход? - person Cory Trese; 18.08.2014
comment
@CoryTrese: для позиционирования окна следует использовать GetMonitorInfo. Вы также можете попробовать EnumDisplaySettings с ENUM_CURRENT_SETTINGS, если вам нужна низкоуровневая информация... - person Anders; 18.08.2014
comment
@Anders: ENUM_CURRENT_SETTINGS определенно включен для более поздних версий Win. Считаете ли вы, что это достойно более подробного описания в ответе? - person Laurie Stearn; 04.09.2016
comment
@LaurieStearn: ИМХО, не для этого вопроса. Если вы просто размещаете окно на определенном мониторе, вам следует использовать GetMonitorInfo. Используйте только низкоуровневый материал, если вам нужно знать глубину цвета или частоту обновления. - person Anders; 04.09.2016
comment
Как мне перечислить все поддерживаемые разрешения/настройки с учетом HMONITOR? - person Shimmy Weitzhandler; 18.06.2020
comment
Моя рабочая станция имеет общий размер 5120 пикселей. Однако SM_CXVIRTUALSCREEN возвращает только 4096 пикселей. Любые идеи..? - person bobobobo; 11.05.2021
comment
@bobobobo DPI? В Win10 есть GetSystemMetricsForDpi. Также убедитесь, что ваше приложение поддерживает DPI. - person Anders; 12.05.2021

Когда система использует виртуализацию DPI (Vista и выше) с помощью GetSystemMetrics или GetWindowRect не удастся получить реальное разрешение экрана (вы получите виртуальное разрешение), если вы не создали Приложение с поддержкой DPI.

Таким образом, лучший вариант здесь (простой и с обратной совместимостью) — использовать EnumDisplaySettings с ENUM_CURRENT_SETTINGS.

person fingeros    schedule 26.12.2016

Это GetSystemMetrics со следующими параметрами:
SM_CXSCREEN ‹ ширина
SM_CYSCREEN ‹ высота

Как говорится (SM_CXSCREEN):

Ширина экрана основного монитора в пикселях. Это то же самое значение, полученное при вызове GetDeviceCaps следующим образом: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).

person Poni    schedule 07.01.2011
comment
Обратите внимание, что GetSystemMetrics существует только для обратной совместимости с поддержкой до Windows 98 (и нескольких мониторов). Вы должны использовать SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN, чтобы показывать пользователям весь экран. - person Ian Boyd; 07.03.2018

Я думаю, что SystemParametersInfo может оказаться полезным.

Изменить: посмотрите также GetMonitorInfo.

person user541686    schedule 07.01.2011
comment
SystemParametersInfo полезен, когда вам нужна только рабочая область = portion of the screen not obscured by the system taskbar or by application desktop toolbars :) - person jave.web; 21.11.2014

Пример MFC Поддержка нескольких мониторов с помощью GetSystemMetrics EnumDisplayMonitors и GetMonitorInfo

Перейдите по этой ссылке: перечисление монитора с исходный код

person Ulterior    schedule 08.09.2011

Удалил около недели назад, потом редактировал 3-4-13.

Вот хороший вариант для ситуаций, когда пользователь решил запустить свой рабочий стол с более низким разрешением (плохая идея) или крайних случаев, когда человек решил получить монитор, который его графический контроллер не может использовать в полной мере:

// get actual size of desktop
RECT actualDesktop;
GetWindowRect(GetDesktopWindow(), &actualDesktop);
person formerBGIuser    schedule 21.01.2013
comment
GetWindowRect(GetDesktopWindow) совершенно неверно. Он намеренно вернет только прямоугольник основного монитора. Прямоугольник окна рабочего стола, возвращаемый GetWindowRect или GetClientRect, всегда равен прямоугольнику основного монитора для совместимости с существующими приложениями. - person Ian Boyd; 03.04.2017

Я использую функцию GetSystemMetrics

GetSystemMetrics(SM_CXSCREEN) возвращает ширину экрана (в пикселях)

GetSystemMetrics(SM_CYSCREEN) - высота в пикселях

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385%28v=vs.85%29.aspx

person Petr    schedule 13.12.2015
comment
Разве это не тот же ответ, что и stackoverflow.com/a/4631313/193892? - person Prof. Falken; 14.12.2015
comment
GetSystemMetrics дает информацию только об основном (первом) мониторе, см. msdn.microsoft.com/en-us/library/windows/desktop/ - person Sandburg; 07.06.2018