在Windows 7/8/10 Win32 C ++中检测/识别显示器连接的端口(HDMI,其他) [英] Detect/identify the port (HDMI, other) the monitor is connected to in Windows 7/8/10 Win32 C++
问题描述
我能够检测到连接到系统的所有监视器。我可以使用以下Windows API调用获取有关它们的很多相关信息:
I am able to detect all the monitors that are connected to my system. I am able to get a lot of relevant information about them using the following Windows API calls:
我正在开发的系统是一个AIO(多合一),带有2个监视器。它具有我可以连接的外部HDMI输出和外部监视器。然后,通过端口复制器,我可以连接第四台显示器。所有监视器都在扩展我的桌面,并且它们都工作正常。
The system I am developing on is an AIO (all-in-one) that comes with 2 monitors. It has an external HDMI output that I can connect and external monitor. Then, through a port replicator I am able to connect the 4th monitor. All of the monitors are extending my desktop and all of them are working fine.
我的任务是检测通过HDMI端口连接的监视器。我可以使用上述API提取的监视器信息没有提供任何特定的信息,通过这些信息我可以检测端口类型(例如HDMI或USB)。
My task is to detect the monitor that is connected through the HDMI port. The monitor information that I am able to extract using the above mentioned API do not give any specific information through which I will be able to detect the port type (e.g. HDMI, or USB).
有人知道要使用什么API吗?谢谢!
Does anyone know what API to use? Thanks!
推荐答案
您可以使用 EnumDisplayDevices
方法来获取显示器的DeviceID
,然后 WmiMonitorConnectionParams
WMI类(从Windows Vista开始提供)和 VideoOutputTechnology
属性,该属性返回< a href = https://msdn.microsoft.com/zh-cn/library/ff546605.aspx rel = noreferrer> D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY
枚举。
You can use the EnumDisplayDevices
method to get the DeviceID
of the monitor and then the WmiMonitorConnectionParams
WMI class (available since Windows Vista) and the VideoOutputTechnology
property which returns a D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY
enumeration.
尝试下一个示例代码
#include "stdafx.h"
#include <atlstr.h>
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
typedef enum _D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY {
D3DKMDT_VOT_UNINITIALIZED = -2,
D3DKMDT_VOT_OTHER = -1,
D3DKMDT_VOT_HD15 = 0,
D3DKMDT_VOT_SVIDEO = 1,
D3DKMDT_VOT_COMPOSITE_VIDEO = 2,
D3DKMDT_VOT_COMPONENT_VIDEO = 3,
D3DKMDT_VOT_DVI = 4,
D3DKMDT_VOT_HDMI = 5,
D3DKMDT_VOT_LVDS = 6,
D3DKMDT_VOT_D_JPN = 8,
D3DKMDT_VOT_SDI = 9,
D3DKMDT_VOT_DISPLAYPORT_EXTERNAL = 10,
D3DKMDT_VOT_DISPLAYPORT_EMBEDDED = 11,
D3DKMDT_VOT_UDI_EXTERNAL = 12,
D3DKMDT_VOT_UDI_EMBEDDED = 13,
D3DKMDT_VOT_SDTVDONGLE = 14,
#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM1_3_M1)
D3DKMDT_VOT_MIRACAST = 15,
#endif
D3DKMDT_VOT_INTERNAL = 0x80000000,
D3DKMDT_VOT_SVIDEO_4PIN = D3DKMDT_VOT_SVIDEO,
D3DKMDT_VOT_SVIDEO_7PIN = D3DKMDT_VOT_SVIDEO,
D3DKMDT_VOT_RF = D3DKMDT_VOT_COMPOSITE_VIDEO,
D3DKMDT_VOT_RCA_3COMPONENT = D3DKMDT_VOT_COMPONENT_VIDEO,
D3DKMDT_VOT_BNC = D3DKMDT_VOT_COMPONENT_VIDEO
} D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY;
_D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY GetConnectorInfo(LPCWSTR ShortDeviceID)
{
_D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY result = D3DKMDT_VOT_OTHER;
BSTR strNetworkResource;
strNetworkResource = L"\\\\.\\root\\WMI";
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(L"WQL", L"SELECT InstanceName, VideoOutputTechnology FROM WmiMonitorConnectionParams",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
if (FAILED(hres))
{
cout << "ExecQuery failed" << " Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
std::exit(1);
}
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
BOOL bFound = false;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn || FAILED(hr))
break;
VARIANT vtProp;
CString DeviceID;
hr = pclsObj->Get(L"InstanceName", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt == VT_NULL) || (vtProp.vt == VT_EMPTY))
{ }
else
{
DeviceID.Format(L"%s", vtProp.bstrVal);
DeviceID = DeviceID.Mid(8, DeviceID.Find(L"\\", 9) - 8);
bFound = DeviceID.Compare(ShortDeviceID) == 0;
}
}
VariantClear(&vtProp);
if (bFound)
{
hr = pclsObj->Get(L"VideoOutputTechnology", 0, &vtProp, 0, 0);// Uint32
if (!FAILED(hr))
{
if ((vtProp.vt == VT_NULL) || (vtProp.vt == VT_EMPTY))
result = D3DKMDT_VOT_OTHER;
else
{
result = (_D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY)vtProp.uintVal;
}
}
}
VariantClear(&vtProp);
pclsObj->Release();
pclsObj = NULL;
if (bFound)
break;
}
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
if (pclsObj != NULL)
pclsObj->Release();
CoUninitialize();
return result;
}
void GetDisplayInfo()
{
DISPLAY_DEVICE lpDisplayDevice;
lpDisplayDevice.cb = sizeof(lpDisplayDevice);
DWORD iDevNum = 0;
CString DeviceID;
while (EnumDisplayDevices(0, iDevNum, &lpDisplayDevice, 0))
{
DISPLAY_DEVICE lpDisplayDevice2;
ZeroMemory(&lpDisplayDevice2, sizeof(lpDisplayDevice2));
lpDisplayDevice2.cb = sizeof(lpDisplayDevice2);
DWORD devMon = 0;
while (EnumDisplayDevices(lpDisplayDevice.DeviceName, devMon, &lpDisplayDevice2, 0))
{
if (lpDisplayDevice2.StateFlags & DISPLAY_DEVICE_ACTIVE && !(lpDisplayDevice2.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
{
DeviceID.Format(L"%s", lpDisplayDevice2.DeviceID);
wcout << DeviceID.GetString() << endl;
DeviceID = DeviceID.Mid(8, DeviceID.Find(L"\\", 9) - 8);
_D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY VideoOutputTechnology = GetConnectorInfo(DeviceID.GetString());
switch (VideoOutputTechnology)
{
case D3DKMDT_VOT_HDMI:
wcout << " VideoOutputTechnology : HDMI" << endl;
break;
case D3DKMDT_VOT_INTERNAL:
wcout << " VideoOutputTechnology : Internal Monitor" << endl;
break;
default:
wcout << " VideoOutputTechnology : " << VideoOutputTechnology << endl;
break;
}
}
devMon++;
ZeroMemory(&lpDisplayDevice2, sizeof(lpDisplayDevice2));
lpDisplayDevice2.cb = sizeof(lpDisplayDevice2);
}
ZeroMemory(&lpDisplayDevice, sizeof(lpDisplayDevice));
lpDisplayDevice.cb = sizeof(lpDisplayDevice);
iDevNum++;
}
}
int main(int argc, char* argv[])
{
GetDisplayInfo();
cout << "press enter to exit" << endl;
cin.get();
return 0;
}
这将返回
MONITOR\CMN15BB\{4d36e96e-e325-11ce-bfc1-08002be10318}\0001
VideoOutputTechnology : Internal Monitor
MONITOR\SNY7702\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000
VideoOutputTechnology : HDMI
这篇关于在Windows 7/8/10 Win32 C ++中检测/识别显示器连接的端口(HDMI,其他)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!