如何区分外部显示器与笔记本电脑的屏幕本身?

让我解释一下我的情况。 我写了一个程序,只有当用户看到屏幕时,才能执行某些绘图/渲染操作。 对于笔记本电脑,这意味着 – 只有当盖子打开时。 要确定我使用GUID_LIDSWITCH_STATE_CHANGE的PBT_POWERSETTINGCHANGE通知,这对于单个监视器系统非常有用。

当有一个或多个连接到笔记本的外接显示器时,会发生问题。 在这种情况下,主笔记本电脑屏幕可能保持不活动状态,只有外部显示器开机。 所以在这种情况下,盖子将被报告为封闭,这应该使我的程序继续渲染。 问题是如何检测这种情况。

我在想,我可以使用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; }