none
C# 如何取得Win10 使用中訊號解析度(Active signal resolution) RRS feed

  • 問題

  • 已嘗試過從WMI尋找跟Display、Monitor相關的所有內容

    regedit中搜尋 "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Hardware Profiles\UnitedVideo\CONTROL\VIDEO

    "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\UnitedVideo\CONTROL\VIDEO"

    這兩個位置中也都沒有Active signal resolution的值可以抓

    使用中訊號解析度(Active signal resolution) 可以由設定 -->顯示器 -->進階顯示設定中看到

    跟"桌面解析度(Desktop resolution)"是不同的

    有沒有人知道可以從哪邊取得Active signal resolution value呢?

    2021年3月25日 上午 04:57

解答

  • 找到答案了。

    https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-displayconfig_video_signal_info

    DISPLAYCONFIG_VIDEO_SIGNAL_INFO::activeSize 就是 Active Signal Resolution。

    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <unordered_map>
    #include "Windows.h"
    
    std::wstring GetDisplayInfo()
    {
        using namespace std;
        wstringstream str;
        try
        {
            struct data
            {
                wstring MonitorName;
                pair<UINT, UINT> ActiveSignalResolution;
            };
            unordered_map<wstring, data> monitors;
            UINT32 sizeP, size_mode;
            if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &sizeP, &size_mode) == ERROR_SUCCESS && size_mode > 0u)
            {
                vector<DISPLAYCONFIG_PATH_INFO> paths(sizeP);
                vector<DISPLAYCONFIG_MODE_INFO> modes(size_mode);
                if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &sizeP, paths.data(), &size_mode, modes.data(), NULL) == ERROR_SUCCESS && !modes.empty())
                {
                    DISPLAYCONFIG_SOURCE_DEVICE_NAME source;
                    source.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
                    source.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME);
                    DISPLAYCONFIG_TARGET_DEVICE_NAME target;
                    target.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
                    target.header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
                    unordered_map<UINT32, data*> temp;
                    for (auto& p : paths)
                    {
                        source.header.adapterId = p.sourceInfo.adapterId;
                        source.header.id = p.sourceInfo.id;
                        target.header.adapterId = p.targetInfo.adapterId;
                        target.header.id = p.targetInfo.id;
                        DisplayConfigGetDeviceInfo(&source.header);
                        DisplayConfigGetDeviceInfo(&target.header);
                        auto const &item = &monitors[source.viewGdiDeviceName];
                        item->MonitorName = target.monitorFriendlyDeviceName;
                        temp[p.targetInfo.id] = item;
                    }
                    for (auto const &m : modes)
                    {
                        if (m.id != 0u)
                        {
                            auto const &item = temp.find(m.id);
                            if (item != temp.end()) item->second->ActiveSignalResolution = make_pair(m.targetMode.targetVideoSignalInfo.activeSize.cx, m.targetMode.targetVideoSignalInfo.activeSize.cy);
                        }
                    }
                }
            }
            DWORD i = 0;
            DISPLAY_DEVICE dd;
            ZeroMemory(&dd, sizeof(dd));
            dd.cb = sizeof(DISPLAY_DEVICE);
            DEVMODE dm;
            ZeroMemory(&dm, sizeof(dm));
            dm.dmSize = sizeof(dm);
            while (EnumDisplayDevicesW(NULL, i, &dd, 0))
            {
                auto const &monitor = monitors.find(dd.DeviceName);
                if (monitor != monitors.end() && EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
                {
                    str << L"Port:\t\t\t\t" << dd.DeviceName << L'\n';
                    str << L"Monitor:\t\t\t" << monitor->second.MonitorName << L'\n';
                    str << L"Graphics card:\t\t\t" << dd.DeviceString << L'\n';
                    str << L"Desktop resolution:\t\t" << dm.dmPelsWidth << L" * " << dm.dmPelsHeight << L'\n';
                    str << L"Active signal resolution:\t" << monitor->second.ActiveSignalResolution.first << L" * " << monitor->second.ActiveSignalResolution.second << L'\n';
                    str << L"Refresh rate (Hz):\t\t" << dm.dmDisplayFrequency << L'\n';
                    str << L"Bits/Pixel:\t\t\t" << dm.dmBitsPerPel << L'\n';
                    str << L"Pixels/Inch:\t\t\t" << dm.dmLogPixels << L'\n';
                    switch (dm.dmDisplayOrientation)
                    {
                        case DMDO_DEFAULT:
                            str << L"Orientation:\t\t\t0\n";
                            break;
                        case DMDO_90:
                            str << L"Orientation:\t\t\t90\n";
                            break;
                        case DMDO_180:
                            str << L"Orientation:\t\t\t180\n";
                            break;
                        case DMDO_270:
                            str << L"Orientation:\t\t\t270\n";
                            break;
                        default:
                            break;
                    }
                    str << L'\n';
                }
                ++i;
            }
        }
        catch (...) {}
        return move(str.str());
    }
    
    int main()
    {
        std::wcout << GetDisplayInfo();
        return 0;
    }

    上面这个是 c++ console 示例。因为我是搞 c++ 的,c# 的水平有限,所以不知道上面的代码怎么写成 c#。您可以创建一个 c++ dll 然后进行调用,或者您可以找 c# 高手把上面的 c++ 代码转换为 c#。无法直接为您提供 c# 代码,对此很抱歉。

    • 已標示為解答 JumboChen 2021年4月1日 下午 04:41
    2021年4月1日 上午 10:15

所有回覆

  • Active Signal Resolution 是 Windows 10 1803 中新增的内容,微软为了推广 UWP,所有新增功能全部只支持 Windows RT API。

    private async Task<string> GetActiveSignalResolution()
    {
        var all = await DeviceInformation.FindAllAsync(DisplayMonitor.GetDeviceSelector());
        if (all != null)
        {
            foreach (var info in all)
            {
                if (info.Kind == DeviceInformationKind.DeviceInterface)
                {
                    var display = await DisplayMonitor.FromInterfaceIdAsync(info.Id);
                    if (display != null)
                    {
                        var size = display.NativeResolutionInRawPixels;
                        return "使用中訊號解析度 " + size.Width.ToString() + " × " + size.Height.ToString();
                    }
                }
            }
        }
        throw new NotSupportedException();
    }

    如果您的项目为 UWP,直接使用上面的代码就可以了。如果您的项目不是 UWP,那就需要添加“Microsoft.Windows.SDK.Contracts NuGet”,请参考这里(https://docs.microsoft.com/zh-tw/windows/apps/desktop/modernize/desktop-to-uwp-enhance)。不过请注意这个“Microsoft.Windows.SDK.Contracts NuGet”只能运行在 Windows 10 1803 及之后发布的新版本 Windows 中,当然在 1803 之前也根本没有 Active Signal Resolution,也就是说想取得这个参数就必须确保您的程式所运行的平台至少得是 Windows 10 1803。

    2021年3月25日 下午 06:45
  • 感謝你的回覆,我的項目是winform(.netframework 4.8),測試以上代碼發現

    當我修改"Activate signal resolution"後沒辦法取得正確的數值,由1920*1080

    改為1600*900,取得的數值始終是1920*1080

    2021年3月26日 上午 02:24
  • 那您是怎么修改“Activate signal resolution”的呢?修改之后您在进阶显示设定中看到的“Activate signal resolution”和“Desktop resolution”分别是多少?还有您是用什么设备(显卡型号和显示器型号)在进行测试?几台显示器?DisplayMonitor.PhysicalConnector 是什么类型?您的 Windows 版本是多少?
    • 已編輯 [-] 2021年3月26日 上午 04:56
    2021年3月26日 上午 04:48
  • 你好,你是根據 [-] 所提供的C# code去改嗎?

    我看了DisplayMonitor的 library,它只提供讀取,沒有寫進或更改的方法

    https://docs.microsoft.com/zh-tw/uwp/api/windows.devices.display.displaymonitor?view=winrt-19041


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for .NET (2003-2017)
    Microsoft rMVP
    My MSMVP Blog
    請記得將對您有幫助的回覆 標示為解答 以幫助其他尋找解答及參與社群討論的朋友們。
    Please remember to click Mark as Answer on the post that helps you. This can be beneficial to other community members reading the thread.


    2021年3月29日 上午 08:43
  • [-] :

    顯卡型號:Intel(R) HD Graphics 4400

    顯示器型號:HP Pavilion 27xw

    Windows 版本:win 10 專業版,版本:2004,OS組建:19041.746

    DisplayMonitor.PhysicalConnector :Dvi

    使用Intel HD Graphics控制台修改"縮放模式",由"縮放全螢幕"改為"保持顯示縮放比"

    修改後在進階顯示設定中看到Activate signal resolution、Desktop resolution 皆是 1600 * 900

    使用1台顯示器測試

    Ken :

    因為我只有讀取的需求,修改會由顯示卡提供的GUI做修改的動作


    • 已編輯 JumboChen 2021年3月29日 上午 09:35 補充回復
    2021年3月29日 上午 09:29
  • 我没有 intel 显卡,我的显卡是 nvidia,他没有修改 activate signal resolution 的功能。所以我把显卡驱动换成了 win10 自带的 microsoft 基础驱动程序进行测试,但无论怎么测试 activate signal resolution 和 NativeResolutionInRawPixels 中的数值都是一样的。我的 win10 目前是 1909(18363.1379)。

    2021年3月29日 上午 11:44
  • [-]:

    請使用"列出所有模式"修改到不同解析度看看,有些解析度的 activate signal resolution、Desktop resolution會不相同,似乎跟螢幕有關?

     居然沒有辦法上傳圖片><

    列出所有模式位置在,相同頁面下的"顯示器1的顯卡內容",Tab "介面卡"最下方的按紐

    我找了Nvidia顯卡測試,NativeResolutionInRawPixels只會顯示最高解析度,調低解析度之後還是取得最高值

    • 已編輯 JumboChen 2021年3月30日 上午 02:05
    2021年3月30日 上午 01:33
  • 根据我的猜测,看来这个所谓的 active signal resolution 就是显示器支持分辨率中大于等于桌面分辨率的那一项,既然如此我们自己把他找出来吧。

    private List<(string Id, uint DesktopResolutionX, uint DesktopResolutionY, uint ActiveSignalResolutionX, uint ActiveSignalResolutionY)> GetActiveSignalResolution()
    {
    	var results = new List<(string, uint, uint, uint, uint)>();
    	var list = new List<(string id, string name, uint w, uint h)>();
    	try
    	{
    		var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
    		foreach (var dm in searcher.Get())
    		{
    			list.Add(((string)dm["PNPDeviceID"], (string)dm["Name"], (UInt32)dm["ScreenWidth"], (UInt32)dm["ScreenHeight"]));
    		}
    	}
    	catch { }
    	if (list.Count > 0)
    	{
    		var resolutions = new List<(uint w, uint h)>();
    		uint w = 0, h = 0;
    		try
    		{
    			var searcher = new ManagementObjectSearcher("\\root\\wmi", "SELECT * FROM WmiMonitorListedSupportedSourceModes");
    			foreach (var monitor in searcher.Get())
    			{
    				foreach (var item in list)
    				{
    					if (((string)monitor["InstanceName"]).StartsWith(item.id, StringComparison.OrdinalIgnoreCase))
    					{
    						resolutions.Clear();
    						foreach (var properties in monitor["MonitorSourceModes"] as ManagementBaseObject[])
    						{
    							resolutions.Add(((UInt16)properties["HorizontalActivePixels"], (UInt16)properties["VerticalActivePixels"]));
    						}
    						if (resolutions.Count > 0)
    						{
    							resolutions.Sort(((uint w, uint h) a, (uint w, uint h) b) =>
    							{
    								if (a.w < b.w) return 1;
    								if (a.w == b.w) return a.h < b.h ? 1 : (a.h == b.h ? 0 : -1);
    								return -1;
    							});
    							foreach (var resolution in resolutions)
    							{
    								if (resolution.w >= item.w && resolution.h >= item.h)
    								{
    									w = resolution.w;
    									h = resolution.h;
    								}
    								else
    								{
    									results.Add((item.name, item.w, item.h, w, h));
    									break;
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    		catch { }
    	}
    	return results;
    }

    在其他能获取显示器和显卡参数的程式中我都没有找到 active signal resolution 这么一个参数,都是只有本机分辨率这一项,nvidia control panel 中也是这一项。如此看来这要么就是微软自己算出来的,比如上面我这样,要么就是未公开的 api。但在之前微软自己写的文章中对 active signal resolution 的描述很像是指新增的 api NativeResolutionInRawPixels,当然那文章也没明确说,而且目前没有任何公开的文章详尽解释这个 active signal resolution 到底是怎么一回事。总之不管微软啦,您看看 NativeResolutionInRawPixels 和我上面的代码是不是能给您一些灵感吧,都不行的话您就只能打电话咨询微软客服了。

    • 已標示為解答 JumboChen 2021年3月31日 上午 01:51
    • 已取消標示為解答 JumboChen 2021年3月31日 上午 03:09
    2021年3月30日 下午 07:35
  • [-]:

    感謝你的協助,active signal resolution主要是會影響,螢幕OSD上顯示的解析度

    使用SELECT * FROM Win32_DesktopMonitor 抓不到 ScreenWidth、ScreenHeight程式顯示值為null

    用wmiexplorer.exe查看Win32_DesktopMonitor 這兩個值也是空白的

    • 已編輯 JumboChen 2021年3月31日 上午 03:20
    2021年3月31日 上午 01:50
  • 空值是因为您的驱动程序不支持 WDDM。

    您可以使用 System.Windows.Forms.SystemInformation.PrimaryMonitorSize 来代替,但这种方式无法支持多显示器。目前还没有找到即支持多显示器又不需要 WDDM 的方法。

    2021年3月31日 上午 05:45
  • System.Windows.Forms.SystemInformation.PrimaryMonitorSize 似乎是取得目前解析度?

    也就是Desktop resolution,如果是的話可以用以下方式取得多螢幕的解析度

    List<WindowsDisplayAPI.Display> Displays = WindowsDisplayAPI.Display.GetDisplays().ToList();            
                Displays.ForEach(name =>
                {
                    Console.WriteLine(name.CurrentSetting.Resolution);               
                });

    2021年3月31日 上午 10:05
  • 无法支持多显示器的意思是,所有 display 相关 API 获得的 desktop resolution 都来自显卡数据,display 指的就是显卡,但如何得知哪个显卡上面连接的是哪些显示器(monitor)呢? desktop resolution 和显示器支持的分辨率必须是同一台显示器才能进行计算啊,如果不是同一台设备就无法进行计算了。所以说获得所有显示器的 desktop resolution 是很简单的,有很多方法都可以做到,但问题是如何得知所得到的 desktop resolution 属于哪一台显示器?这个才是问题的关键,当前我还没有找到相关解决方案。就当前而言如果不使用 Win32_DesktopMonitor 就不能对多台显示器进行计算了。
    2021年3月31日 下午 12:51
  • 或許可以用以下方式取得指定螢幕解析度,我再試試看你提供的計算方式,感謝幫忙

    Displays = WindowsDisplayAPI.Display.GetDisplays().ToList();
                Displays.ForEach(name =>
                {
                    Console.WriteLine(name.CurrentSetting.Resolution);
                    DisplayNames.Add(name.ToPathDisplayTarget().FriendlyName);
                });
    // 取得指定螢幕解析度
                Console.WriteLine(Displays.Where(d => d.DisplayName.Equals(@"\\.\DISPLAY1")).FirstOrDefault().CurrentSetting.Resolution);

    將你提供的計算方式修改如下,實際解析度:Desktop resolution:1600 * 900 , active signal resolution:1920 * 1080

    計算結果會是 name,1600,900,1600,900

    private List<(string Id, uint DesktopResolutionX, uint DesktopResolutionY, uint ActiveSignalResolutionX, uint ActiveSignalResolutionY)> GetActiveSignalResolution()
            {
                var results = new List<(string, uint, uint, uint, uint)>();
                var list = new List<(string id, string name, uint w, uint h)>();
                try
                {
                    var dis = Displays.Where(d => d.DisplayName.Equals(@"\\.\DISPLAY1")).FirstOrDefault();
                    string ID = dis.DevicePath.Replace(@"\\?\", "");
                    ID = ID.Remove(ID.LastIndexOf('#')).Replace("#", @"\");
                    list.Add((ID, dis.DisplayName, (UInt32)dis.CurrentSetting.Resolution.Width, (UInt32)dis.CurrentSetting.Resolution.Height));
                }
                catch { }
                if (list.Count > 0)
                {
                    var resolutions = new List<(uint w, uint h)>();
                    uint w = 0, h = 0;
                    try
                    {
                        var searcher = new ManagementObjectSearcher("\\root\\wmi", "SELECT * FROM WmiMonitorListedSupportedSourceModes");
                        foreach (var monitor in searcher.Get())
                        {
                            foreach (var item in list)
                            {
                                if (((string)monitor["InstanceName"]).Contains(item.id))
                                {
                                    resolutions.Clear();
                                    foreach (var properties in monitor["MonitorSourceModes"] as ManagementBaseObject[])
                                    {
                                        resolutions.Add(((UInt16)properties["HorizontalActivePixels"], (UInt16)properties["VerticalActivePixels"]));
                                    }
                                    if (resolutions.Count > 0)
                                    {
                                        resolutions.Sort(((uint w, uint h) a, (uint w, uint h) b) =>
                                        {
                                            if (a.w < b.w) return 1;
                                            if (a.w == b.w) return a.h < b.h ? 1 : (a.h == b.h ? 0 : -1);
                                            return -1;
                                        });
                                        foreach (var resolution in resolutions)
                                        {
                                            if (resolution.w >= item.w && resolution.h >= item.h)
                                            {
                                                w = resolution.w;
                                                h = resolution.h;
                                            }
                                            else
                                            {
                                                results.Add((item.name, item.w, item.h, w, h));
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                }
                return results;
            }



    • 已編輯 JumboChen 2021年4月1日 上午 02:45
    2021年4月1日 上午 01:41
  • 您改过的代码是无法正常工作的,上面我已经解释了,如果您不使用 Win32_DesktopMonitor,就没有办法获得和显示器(monitor)硬件对应的 PNPDeviceID,在这种情况下是不可能支持多台显示器的。只能支持单台显示器,单台显示器的代码应该是下面这样。

    private (uint ActiveSignalResolutionX, uint ActiveSignalResolutionY) GetActiveSignalResolution()
    {
    	uint w = 0, h = 0;
    	try
    	{
    		var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
    		foreach (var vc in searcher.Get())
    		{
    			w = (UInt32)vc["CurrentHorizontalResolution"];
    			h = (UInt32)vc["CurrentVerticalResolution"];
    			break;
    		}
    	}
    	catch { }
    	try
    	{
    		var resolutions = new List<(uint w, uint h)>();
    		var searcher = new ManagementObjectSearcher("\\root\\wmi", "SELECT * FROM WmiMonitorListedSupportedSourceModes");
    		foreach (var monitor in searcher.Get())
    		{
    			foreach (var properties in monitor["MonitorSourceModes"] as ManagementBaseObject[])
    			{
    				resolutions.Add(((UInt16)properties["HorizontalActivePixels"], (UInt16)properties["VerticalActivePixels"]));
    			}
    			break;
    		}
    		if (resolutions.Count > 0)
    		{
    			resolutions.Sort(((uint w, uint h) a, (uint w, uint h) b) =>
    			{
    				if (a.w < b.w) return 1;
    				if (a.w == b.w) return a.h < b.h ? 1 : (a.h == b.h ? 0 : -1);
    				return -1;
    			});
    			uint width = 0, height = 0;
    			foreach (var resolution in resolutions)
    			{
    				if (resolution.w >= w && resolution.h >= h)
    				{
    					width = resolution.w;
    					height = resolution.h;
    				}
    				else
    				{
    					w = width;
    					h = height;
    					break;
    				}
    			}
    		}
    	}
    	catch { }
    	return (w, h);
    }

    2021年4月1日 上午 03:27
  • 找到答案了。

    https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-displayconfig_video_signal_info

    DISPLAYCONFIG_VIDEO_SIGNAL_INFO::activeSize 就是 Active Signal Resolution。

    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <unordered_map>
    #include "Windows.h"
    
    std::wstring GetDisplayInfo()
    {
        using namespace std;
        wstringstream str;
        try
        {
            struct data
            {
                wstring MonitorName;
                pair<UINT, UINT> ActiveSignalResolution;
            };
            unordered_map<wstring, data> monitors;
            UINT32 sizeP, size_mode;
            if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &sizeP, &size_mode) == ERROR_SUCCESS && size_mode > 0u)
            {
                vector<DISPLAYCONFIG_PATH_INFO> paths(sizeP);
                vector<DISPLAYCONFIG_MODE_INFO> modes(size_mode);
                if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &sizeP, paths.data(), &size_mode, modes.data(), NULL) == ERROR_SUCCESS && !modes.empty())
                {
                    DISPLAYCONFIG_SOURCE_DEVICE_NAME source;
                    source.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
                    source.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME);
                    DISPLAYCONFIG_TARGET_DEVICE_NAME target;
                    target.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
                    target.header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
                    unordered_map<UINT32, data*> temp;
                    for (auto& p : paths)
                    {
                        source.header.adapterId = p.sourceInfo.adapterId;
                        source.header.id = p.sourceInfo.id;
                        target.header.adapterId = p.targetInfo.adapterId;
                        target.header.id = p.targetInfo.id;
                        DisplayConfigGetDeviceInfo(&source.header);
                        DisplayConfigGetDeviceInfo(&target.header);
                        auto const &item = &monitors[source.viewGdiDeviceName];
                        item->MonitorName = target.monitorFriendlyDeviceName;
                        temp[p.targetInfo.id] = item;
                    }
                    for (auto const &m : modes)
                    {
                        if (m.id != 0u)
                        {
                            auto const &item = temp.find(m.id);
                            if (item != temp.end()) item->second->ActiveSignalResolution = make_pair(m.targetMode.targetVideoSignalInfo.activeSize.cx, m.targetMode.targetVideoSignalInfo.activeSize.cy);
                        }
                    }
                }
            }
            DWORD i = 0;
            DISPLAY_DEVICE dd;
            ZeroMemory(&dd, sizeof(dd));
            dd.cb = sizeof(DISPLAY_DEVICE);
            DEVMODE dm;
            ZeroMemory(&dm, sizeof(dm));
            dm.dmSize = sizeof(dm);
            while (EnumDisplayDevicesW(NULL, i, &dd, 0))
            {
                auto const &monitor = monitors.find(dd.DeviceName);
                if (monitor != monitors.end() && EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
                {
                    str << L"Port:\t\t\t\t" << dd.DeviceName << L'\n';
                    str << L"Monitor:\t\t\t" << monitor->second.MonitorName << L'\n';
                    str << L"Graphics card:\t\t\t" << dd.DeviceString << L'\n';
                    str << L"Desktop resolution:\t\t" << dm.dmPelsWidth << L" * " << dm.dmPelsHeight << L'\n';
                    str << L"Active signal resolution:\t" << monitor->second.ActiveSignalResolution.first << L" * " << monitor->second.ActiveSignalResolution.second << L'\n';
                    str << L"Refresh rate (Hz):\t\t" << dm.dmDisplayFrequency << L'\n';
                    str << L"Bits/Pixel:\t\t\t" << dm.dmBitsPerPel << L'\n';
                    str << L"Pixels/Inch:\t\t\t" << dm.dmLogPixels << L'\n';
                    switch (dm.dmDisplayOrientation)
                    {
                        case DMDO_DEFAULT:
                            str << L"Orientation:\t\t\t0\n";
                            break;
                        case DMDO_90:
                            str << L"Orientation:\t\t\t90\n";
                            break;
                        case DMDO_180:
                            str << L"Orientation:\t\t\t180\n";
                            break;
                        case DMDO_270:
                            str << L"Orientation:\t\t\t270\n";
                            break;
                        default:
                            break;
                    }
                    str << L'\n';
                }
                ++i;
            }
        }
        catch (...) {}
        return move(str.str());
    }
    
    int main()
    {
        std::wcout << GetDisplayInfo();
        return 0;
    }

    上面这个是 c++ console 示例。因为我是搞 c++ 的,c# 的水平有限,所以不知道上面的代码怎么写成 c#。您可以创建一个 c++ dll 然后进行调用,或者您可以找 c# 高手把上面的 c++ 代码转换为 c#。无法直接为您提供 c# 代码,对此很抱歉。

    • 已標示為解答 JumboChen 2021年4月1日 下午 04:41
    2021年4月1日 上午 10:15
  • 沒錯!!!這就是答案,非常感謝
    2021年4月1日 下午 04:42