c++ - 使用 WinApi 获取与“高级显示设置”面板中相同的显示名称
问题描述
使用与通过 WinApi 获取显示名称相关的其他问题的答案相同的方法(使用EnumDisplayDevicesW
同时将设备名称作为第一个参数传递,类似于例如这个),我已经能够取得部分成功。我遇到的问题是我得到的信息不完整。在桌面右击,选择“显示设置”,然后选择底部的“高级显示设置”即可进入“高级显示设置”面板,显示如下显示:
DELL P2414H(DisplayPort)
AOC AG271QG
BenQ PJ
但是,通过使用EnumDisplayDevicesW
调用,我提取了以下内容:
AOC AG271QG
DELL P2414H(DisplayPort)
Generic PnP Monitor
虽然顺序对我来说并不重要,但问题是我得到的是“通用 PnP 监视器”而不是更有用的“BenQ PJ”(这不是我希望的确切型号,但至少仍然提供一些信息)。我该怎么做才能提取“BenQ PJ”而不是“Generic PnP Monitor”(最好保留在 WinApi 中)?
解决方案
您可以使用EDID获取 Monitor 信息
可以使用 WMI 读取 EDID
比如用WmiOpenBlock等测试,减少C++中WMI的代码=>
我得到我的显示器:
Instance Name = DISPLAY\PHLC085\4&20634529&0&UID65793_0
User Friendly Name = 247ELH
Manufacturer Name = PHL
Product Code ID = C085
Serial Number ID = AU01307001613
包括并定义 =>
#define _CRT_NON_CONFORMING_SWPRINTFS
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <tchar.h>
#include <initguid.h>
#include <wmistr.h>
DEFINE_GUID(WmiMonitorID_GUID, 0x671a8285, 0x4edb, 0x4cae, 0x99,0xfe,0x69,0xa1,0x5c,0x48,0xc0,0xbc );
typedef struct WmiMonitorID {
USHORT ProductCodeID[16];
USHORT SerialNumberID[16];
USHORT ManufacturerName[16];
UCHAR WeekOfManufacture;
USHORT YearOfManufacture;
USHORT UserFriendlyNameLength;
USHORT UserFriendlyName[1];
} WmiMonitorID, *PWmiMonitorID;
#define OFFSET_TO_PTR(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
typedef HRESULT(WINAPI*WOB) (IN LPGUID lpGUID, IN DWORD nAccess, OUT LONG*);
WOB WmiOpenBlock;
typedef HRESULT(WINAPI*WQAD) (IN LONG hWMIHandle, ULONG* nBufferSize, OUT UCHAR * pBuffer);
WQAD WmiQueryAllData;
typedef HRESULT(WINAPI*WCB) (IN LONG);
WCB WmiCloseBlock;
测试代码 =>
HRESULT hr = E_FAIL;
LONG hWmiHandle;
PWmiMonitorID MonitorID;
HINSTANCE hDLL = LoadLibrary(L"Advapi32.dll");
WmiOpenBlock = (WOB)GetProcAddress(hDLL, "WmiOpenBlock");
WmiQueryAllData = (WQAD)GetProcAddress(hDLL, "WmiQueryAllDataW");
WmiCloseBlock = (WCB)GetProcAddress(hDLL, "WmiCloseBlock");
if (WmiOpenBlock != NULL && WmiQueryAllData && WmiCloseBlock)
{
WCHAR pszDeviceId[256] = L"";
hr = WmiOpenBlock((LPGUID)&WmiMonitorID_GUID, GENERIC_READ, &hWmiHandle);
if (hr == ERROR_SUCCESS)
{
ULONG nBufferSize = 0;
UCHAR *pAllDataBuffer = 0;
PWNODE_ALL_DATA pWmiAllData;
hr = WmiQueryAllData(hWmiHandle, &nBufferSize, 0);
if (hr == ERROR_INSUFFICIENT_BUFFER)
{
pAllDataBuffer = (UCHAR*)malloc(nBufferSize);
hr = WmiQueryAllData(hWmiHandle, &nBufferSize, pAllDataBuffer);
if (hr == ERROR_SUCCESS)
{
while (1)
{
pWmiAllData = (PWNODE_ALL_DATA)pAllDataBuffer;
if (pWmiAllData->WnodeHeader.Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE)
MonitorID = (PWmiMonitorID)&pAllDataBuffer[pWmiAllData->DataBlockOffset];
else
MonitorID = (PWmiMonitorID)&pAllDataBuffer[pWmiAllData->OffsetInstanceDataAndLength[0].OffsetInstanceData];
ULONG nOffset = 0;
WCHAR *pwsInstanceName = 0;
nOffset = (ULONG)pAllDataBuffer[pWmiAllData->OffsetInstanceNameOffsets];
pwsInstanceName = (WCHAR*)OFFSET_TO_PTR(pWmiAllData, nOffset + sizeof(USHORT));
WCHAR wsText[255] = L"";
swprintf(wsText, L"Instance Name = %s\r\n", pwsInstanceName);
OutputDebugString(wsText);
WCHAR *pwsUserFriendlyName;
pwsUserFriendlyName = (WCHAR*)MonitorID->UserFriendlyName;
swprintf(wsText, L"User Friendly Name = %s\r\n", pwsUserFriendlyName);
OutputDebugString(wsText);
WCHAR *pwsManufacturerName;
pwsManufacturerName = (WCHAR*)MonitorID->ManufacturerName;
swprintf(wsText, L"Manufacturer Name = %s\r\n", pwsManufacturerName);
OutputDebugString(wsText);
WCHAR *pwsProductCodeID;
pwsProductCodeID = (WCHAR*)MonitorID->ProductCodeID;
swprintf(wsText, L"Product Code ID = %s\r\n", pwsProductCodeID);
OutputDebugString(wsText);
WCHAR *pwsSerialNumberID;
pwsSerialNumberID = (WCHAR*)MonitorID->SerialNumberID;
swprintf(wsText, L"Serial Number ID = %s\r\n", pwsSerialNumberID);
OutputDebugString(wsText);
if (!pWmiAllData->WnodeHeader.Linkage)
break;
pAllDataBuffer += pWmiAllData->WnodeHeader.Linkage;
}
free(pAllDataBuffer);
}
}
WmiCloseBlock(hWmiHandle);
}
}
推荐阅读
- c# - 创建一个通用列表
- javascript - 如何获取对象的总数组
- node.js - 如何使用 nodejs 从图像中查找自定义徽标
- c++ - jpegenc - 使用 VideoWrite() OpenCV 函数编码 + 存储
- angular - Angular 表单验证如何将嵌套表单控件添加到 FormData
- java - 如何使用 Spark(JAVA API)预测样本外的值
- java - 从单独的包继承的公共方法无法解析,而直接定义的公共方法解析
- spartacus-storefront - Spartacus (SmartEdit) 中是否支持自定义 AbstractCMSComponentContainer?
- amazon-web-services - 升级 AWS RDS 时出现“不支持最大存储大小”
- html - 使用图标 (CSS) 将文本集中在按钮中