在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++

查看:356
本文介绍了在Windows 7/8/10 Win32 C ++中检测/识别显示器连接的端口(HDMI,其他)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够检测到连接到系统的所有监视器。我可以使用以下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:

EnumDisplayMonitors

GetMonitorInfo

EnumDisplayDevices

我正在开发的系统是一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆