本文根据windows系统提供的设备api, 配合注册表访问接口 获取电脑所连接显示器的厂商名称列表,代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <bitset>
#include <windows.h>
#include <winreg.h>
void get_display_physical_size(HDC hdc, unsigned long &width_millimeters, unsigned long &height_millimeters);
static void Stringsplit(const std::string& str, const std::string& split, std::vector<std::string>& res)
{
char* strc = new char[str.size() + 1];
strcpy(strc, str.c_str()); // 将str拷贝到 char类型的strc中
char* temp = strtok(strc, split.c_str());
while (temp != NULL)
{
res.push_back(std::string(temp));
temp = strtok(NULL, split.c_str()); // 下一个被分割的串
}
delete[] strc;
}
BOOL CALLBACK _MonitorEnumProc(HMONITOR hMonitor, // handle to display monitor
HDC hdcMonitor, // handle to monitor DC
LPRECT lprcMonitor, // monitor intersection rectangle
LPARAM dwData // data
)
{
std::vector<stMonitorInfo> *pvec_monitor = (std::vector<stMonitorInfo>*) dwData;
MONITORINFOEX miex;
miex.cbSize = sizeof(miex);
if (GetMonitorInfo(hMonitor, &miex))
{
stMonitorInfo monitor_info;
monitor_info.resolution_width = miex.rcMonitor.right - miex.rcMonitor.left;
monitor_info.resolution_heght = miex.rcMonitor.bottom - miex.rcMonitor.top;
DEVMODE devMode = { 0 };
devMode.dmSize = sizeof(devMode);
devMode.dmDriverExtra = sizeof(0);
if (EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &devMode))
{
if (devMode.dmFields & DM_DISPLAYFREQUENCY)
{
monitor_info.frequency = devMode.dmDisplayFrequency;
}
}
//为了防止edid不对,采取HDC方式获取
HDC hdc = CreateDC(NULL, miex.szDevice, NULL, NULL);
if (hdc)
{
get_display_physical_size(hdc, monitor_info.device_width_cm, monitor_info.device_heght_cm);
DeleteDC(hdc);
}
DISPLAY_DEVICE data = { 0 };
data.cb = sizeof(data);
if (EnumDisplayDevices(miex.szDevice, 0, &data, EDD_GET_DEVICE_INTERFACE_NAME))
{
//DeviceID "\\\\?\\DISPLAY#DELA07A#5&30f41049&0&UID4352#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" char[128]
//开始解析
printf("Monitor DeviceID:%s\r\n", data.DeviceID);
std::vector<std::string> vec_data;
Stringsplit(data.DeviceID, "#", vec_data);
if (vec_data.size() >= 3)
{
char szKey[1024] = "";
sprintf(szKey, "SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\%s\\%s\\Device Parameters", vec_data[1].c_str(), vec_data[2].c_str());
//std::vector<BYTE> edid;
BYTE edid[1024] = { 0 };
HKEY hKey;
long lRet;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hKey);
unsigned long dwSize = sizeof(edid);
if(ERROR_SUCCESS == RegQueryValueEx(
hKey, // handle to key
"EDID", // value name
NULL, // reserved
NULL, // type buffer
(LPBYTE)edid, // data buffer
&dwSize // size of data buffer
))
{
//这里应该计算校验和如果校验和不对则忽略
if (monitor_info.device_width_cm == 0 && monitor_info.device_heght_cm == 0)
{
monitor_info.device_width_cm = edid[0x15];
monitor_info.device_heght_cm = edid[0x16];
}
//给一个默认名称,方式edid数据里面没有名称
lstrcpyn(monitor_info.szname, vec_data[1].c_str(), 260);
//避免大小端问题
std::bitset<8> bits0(edid[8]);
std::bitset<8> bits1(edid[9]);
std::string strBits = bits0.to_string() + bits1.to_string();
std::bitset<5> prd0(strBits, 1);
std::bitset<5> prd1(strBits, 6);
std::bitset<5> prd2(strBits, 11);
ULONG lval0 = prd0.to_ulong();
ULONG lval1 = prd1.to_ulong();
ULONG lval2 = prd2.to_ulong();
monitor_info.szfirm[0] = TCHAR('A') + lval0 - 1;
monitor_info.szfirm[1] = TCHAR('A') + lval1 - 1;
monitor_info.szfirm[2] = TCHAR('A') + lval2 - 1;
//获取显示器名称
std::vector<int> vec = { 0x36, 0x48, 0x5a, 0x6c };
for (int i = 0; i < vec.size(); ++i)
{
int nindex = vec[i];
if (edid[nindex] == 0x00 && edid[nindex + 1] == 0x00 && edid[nindex + 2] == 0x00 && edid[nindex + 3] == 0xfc)
{
std::string str((char *)&edid[nindex + 4], 14);
//删除\0 \n 0x20
if (str[0] == 0) str = str.substr(1);
while (!str.empty())
{
if (str[str.size() - 1] == 0x20 || str[str.size() - 1] == '\n')
{
str = str.substr(0, str.size() - 1);
continue;
}
break;
}
lstrcpy(monitor_info.szname, str.c_str());
}
}
}
}
}
pvec_monitor->push_back(monitor_info);
}
return TRUE;
}
void get_display_resolution(int &width, int &height)
{
static int Width{ GetSystemMetrics(SM_CXSCREEN) };
static int Heigth{ GetSystemMetrics(SM_CYSCREEN) };
width = Width;
height = Heigth;
}
void get_display_physical_size(HDC hdc, unsigned long &width_millimeters, unsigned long &height_millimeters)
{
bool bRelease = false;
if (hdc == NULL)
{
bRelease = true;
hdc = GetDC(NULL);
}
width_millimeters = GetDeviceCaps(hdc, HORZSIZE) / 10;
height_millimeters = GetDeviceCaps(hdc, VERTSIZE) / 10;
if (bRelease)
ReleaseDC(NULL, hdc);
}
void get_monitor_info(std::vector<stMonitorInfo> &vec_monitor)
{
EnumDisplayMonitors(NULL, NULL, _MonitorEnumProc, (LPARAM)&vec_monitor);
}
int main() {
std::vector<stMonitorInfo> vec_monitor;
get_monitor_info(vec_monitor);
for(int i = 0; i < vec_monitor.size(); i++)
{
printf("m%d:%s-%s\n",i,vec_monitor[i].szfirm,vec_monitor[i].szname);
}
return 0;
}
代码依赖库文件windows系统 “Dxva2.lib”