Позвольте мне объяснить мою ситуацию. Я пишу программу, которая должна выполнять определенные операции рисования и рендеринга только тогда, когда пользователь видит экран. В случае ноутбука это означает - только когда крышка открыта. Чтобы определить, что я использую уведомление PBT_POWERSETTINGCHANGE для GUID_LIDSWITCH_STATE_CHANGE, которое отлично подходит для одной системы мониторинга.
Проблема возникает, когда один или несколько внешних подключенных мониторов подключены к ноутбуку. В этой ситуации основной экран ноутбука может оставаться неактивным, а только внешний монитор (мониторы) включены. Таким образом, в этом случае крышка будет сообщаться как закрытая, что должно сделать мою программу продолжением рендеринга. Проблема заключается в том, как обнаружить эту ситуацию.
Я думал, что могу подсчитывать мониторы с помощью GetSystemMetrics(SM_CMONITORS)
но в этом случае я не знаю, откуда идет монитор, или, другими словами, это "собственный" экран для ноутбука или внешнее подключение один.
Поэтому мой вопрос: могу ли я дефференцировать между любыми внешними мониторами, подключенными к системе, и "родным" экраном ноутбука?
Вы можете вызвать GetMonitorInfo и опросить флаг, который был возвращен в структуре MonitorInfo. Найдите MONITORINFOF_PRIMARY.
К сожалению, то, о чем вы просите, не так прямолинейно, как кажется. Невозможно различать внешний монитор и собственный экран устройства:
Флаг MONITORINFOF_PRIMARY
будет установлен для любого монитора, настроенного как первичный, и может быть любым внешним монитором.
GetSystemMetrics(SM_CMONITORS)
вернет число физических мониторов и не повлияет на открытие или закрытие крышки.
Тем не менее, я использовал приведенный ниже код, который может перечислять (и считать в вашем случае) "удобные" мониторы или те, которые в настоящее время "используются" Windows. Код должен работать в ситуации, когда экран выключается, закрывая крышку устройства.
Он поставляется с одним предупреждением - он должен запускаться только из интерактивной сессии пользователя. Другими словами, вы не можете вызвать его из приложения-службы.
int CountUsableMonitors()
{
int count = 0;
for(int i = 0; ; i++)
{
DISPLAY_DEVICE dd = {0};
dd.cb = sizeof(dd);
//Get display adapter info
if(!::EnumDisplayDevices(NULL, i, &dd, 0))
{
break;
}
//Only if active
if(dd.StateFlags & DISPLAY_DEVICE_ACTIVE)
{
DISPLAY_DEVICE dd2 = {0};
dd2.cb = sizeof(dd2);
//Get monitor info
if(::EnumDisplayDevices(dd.DeviceName, 0, &dd2, 0))
{
if(dd2.StateFlags & (DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED))
{
count++;
}
}
}
}
return count;
}