C++ windows显示器相关信息获取 - 艺文笔记
Tue Mar 21 2023 08:34:11 GMT+0000 (Coordinated Universal Time)
Saved by @leawoliu
#include <windows.h> #include <iostream> #include <vector> // 获取显示器信息 struct monitor_info { bool primary_device; // 主显示器 std::wstring HardwareID; // 硬件ID SIZE size_; // 屏幕物理大小(单位毫米) SIZE physical_pixel_; // 物理分辨率(单位像素) SIZE logical_pixel_; // 逻辑分辨率(单位像素) float inches; // 屏幕英寸 }; std::wstring GetHardwareID(const std::wstring& DeviceID) { std::wstring::size_type pos = 0, lastpos = 0; std::wstring::size_type len = DeviceID.length(); std::vector<std::wstring> params; for (; ;) { pos = DeviceID.find_first_of(L"#", lastpos); if (pos == std::wstring::npos) { if (pos >= len) break; } params.push_back(DeviceID.substr(lastpos, pos - lastpos)); lastpos = pos + 1; } return params.size() >= 2 ? params[1] : std::wstring(); } void GetMonitorInfo(std::vector<monitor_info>& vcMonitorInfo) { struct DISPLAY_SETTING { DISPLAY_DEVICE device; DEVMODE devmode; }; std::vector<DISPLAY_SETTING> vcDisplay; for (int devno = 0; ; devno++) { DISPLAY_DEVICE device = { 0 }; device.cb = sizeof(DISPLAY_DEVICE); /* 要查询当前会话中的所有显示设备,请在循环中调用此函数,从iDevNum设置为0开始, 并递增iDevNum直到函数失败。要选择桌面中的所有显示设备,请仅使用DISPLAY_DEVICE 结构中具有DISPLAY_DEVICE_ATTACHED_TO_DESKTOP标志的显示设备。 */ if (!::EnumDisplayDevices(NULL, devno, &device, 0)) { break; } DEVMODE devmode = { 0 }; if (!::EnumDisplaySettings(device.DeviceName, ENUM_REGISTRY_SETTINGS, &devmode)) { break; } if (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { DISPLAY_SETTING setting = { 0 }; setting.device = device; setting.devmode = devmode; vcDisplay.push_back(setting); } } for (auto iter : vcDisplay) { HDC hdc = ::CreateDC(L"DISPLAY", iter.device.DeviceName, NULL, NULL); if (hdc == NULL) { continue; } int cx = ::GetDeviceCaps(hdc, HORZSIZE); int cy = ::GetDeviceCaps(hdc, VERTSIZE); float unit_inches_millimeter = 25.4f; // 25.4毫米/英寸 if (cx <= 0 || cy <= 0) { ::DeleteDC(hdc); continue; } monitor_info item; item.size_ = { cx ,cy }; item.physical_pixel_ = { (LONG)iter.devmode.dmPelsWidth ,(LONG)iter.devmode.dmPelsHeight }; item.inches = (float)sqrt(pow(cx, 2.0f) + pow(cy, 2.0f)) / unit_inches_millimeter; int log_pixels_x = ::GetDeviceCaps(hdc, LOGPIXELSX); int log_pixels_y = ::GetDeviceCaps(hdc, LOGPIXELSY); if (log_pixels_x == 96 && log_pixels_y == 96) { item.logical_pixel_ = { ::GetDeviceCaps(hdc,HORZRES),::GetDeviceCaps(hdc,VERTRES) }; } else { LONG logical_pixel_x = (int)(96.0f / log_pixels_x) * item.physical_pixel_.cx; LONG logical_pixel_y = (int)(96.0f / log_pixels_y) * item.physical_pixel_.cy; item.logical_pixel_ = { logical_pixel_x,logical_pixel_y }; } DISPLAY_DEVICE device = { 0 }; device.cb = sizeof(DISPLAY_DEVICE); if (::EnumDisplayDevices(iter.device.DeviceName, 0, &device, EDD_GET_DEVICE_INTERFACE_NAME)) { item.HardwareID = GetHardwareID(device.DeviceID); } // 通过DISPLAY_DEVICE_PRIMARY_DEVICE判断是否为主显示器 item.primary_device = (iter.device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE); vcMonitorInfo.push_back(item); ::DeleteDC(hdc); } } int main() { std::vector<monitor_info> vcMonitorInfo; GetMonitorInfo(vcMonitorInfo); std::cout << "显示器个数:" << vcMonitorInfo.size() << std::endl; for (size_t i = 0; i < vcMonitorInfo.size(); ++i) { std::cout << std::endl; std::cout << "显示器" << i + 1 << ":" << std::endl; std::cout << "是否为主显示器: " << (vcMonitorInfo[i].primary_device ? "是" : "否") << std::endl; std::wcout << L"显示器硬件id: " << vcMonitorInfo[i].HardwareID.c_str() << std::endl; std::cout << "物理分辨率: " << vcMonitorInfo[i].physical_pixel_.cx << " x " << vcMonitorInfo[i].physical_pixel_.cy << std::endl; std::cout << "逻辑分辨率: " << vcMonitorInfo[i].logical_pixel_.cx << " x " << vcMonitorInfo[i].logical_pixel_.cy << std::endl; std::cout << "屏幕英寸: " << vcMonitorInfo[i].inches << std::endl; } system("pause"); return 0; }
Comments