首页 > 编程语言 >C# 通过注册表、API两种方式获取显示器的分辨率尺寸

C# 通过注册表、API两种方式获取显示器的分辨率尺寸

时间:2024-11-01 15:41:31浏览次数:1  
标签:IntPtr const C# Height int API SM 注册表

  还是那个项目……还是那个领导……要求获取用户的显示器尺寸。一脸懵逼???还是照做……

  获取显示器的尺寸,有两种方法。第一种是通过查询注册表中,存储的指定显示器的相关信息;第二种是通过windows API

1、查询注册表中存储的显示器信息

复制代码
/// <summary>
/// 获取显示器的相关硬件ID
/// </summary>
/// <returns></returns>
public static List<string> GetMonitorPnpDeviceId()
{
    List<string> rt = new List<string>();
    using (ManagementClass mc = new ManagementClass("Win32_DesktopMonitor"))
    {
        using (ManagementObjectCollection moc = mc.GetInstances())
        {
            foreach (var o in moc)
            {
                var each = (ManagementObject)o;
                object obj = each.Properties["PNPDeviceID"].Value;
                if (obj == null)
                    continue;

                rt.Add(obj.ToString());
            }
        }
    }

    return rt;
}

/// <summary>
/// 通过硬件ID查找系统存储的相关信息
/// </summary>
/// <param name="monitorPnpDevId"></param>
/// <returns></returns>
public static byte[] GetMonitorEdid(string monitorPnpDevId)
{
    return (byte[])Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\" + monitorPnpDevId + @"\Device Parameters", "EDID", new byte[] { });
}

/// <summary>
/// 获取显示器物理尺寸(cm)
/// </summary>
/// <param name="monitorPnpDevId">屏幕信息</param>
/// <returns>物理尺寸</returns>
public static Size GetMonitorPhysicalSize(string monitorPnpDevId)
{
    byte[] edid = GetMonitorEdid(monitorPnpDevId);
    if (edid.Length < 23)
        return Size.Empty;

    return new Size(edid[21], edid[22]);
}

/// <summary>
/// 通过屏显示器理尺寸转换为显示器大小(inch)
/// </summary>
/// <param name="moniPhySize"></param>
/// <returns></returns>
public static  float MonitorScaler(Size moniPhySize)
{
    double mDSize = Math.Sqrt(Math.Pow(moniPhySize.Width, 2) + Math.Pow(moniPhySize.Height, 2)) / 2.54d;
    return (float)Math.Round(mDSize, 1);
}
复制代码

  使用上述方法,稍微有点繁琐,需要调用多次,才能获得相关的信息。但好处是,可以获得多个显示器的尺寸信息。问题是……公司用的是云桌面,虚拟机,TMD这个方法获取不到数据(不知道是不是我操作的不对……)???所以又老老实实使用API来获取了。

2、使用Windows API 查询显示器信息

  1、使用GetSystemMetrics API获取

  GetSystemMetrics API最为简单,直接引用API,传入对应的变量,获得相关的数据,引用API调用即可:

[DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex);

  其中,nIndex的类型如下:

复制代码
class SystemMetricsType
{
    const int SM_CXSCREEN = 0;//屏幕宽度
    const int SM_CYSCREEN = 1;//屏幕高度
    const int SM_CXVSCROLL = 2;//垂直滚动条的宽度
    const int SM_CYHSCROLL = 3;//水平滚动条的宽度
    const int SM_CYCAPTION = 4;//Height of windows caption 实际标题高度加上SM_CYBORDER
    const int SM_CXBORDER = 5;//Width of no-sizable borders 无法测量的窗口框架宽度
    const int SM_CYBORDER = 6;//Height of non-sizable borders 无法测量的窗口框架高度
    const int SM_CXDLGFRAME = 7;//Width of dialog box borders
    const int SM_CYDLGFRAME = 8;//Height of dialog box borders
    const int SM_CYHTHUMB = 9;//Height of scroll box on horizontal scroll bar 水平滚动条上滑块的高度
    const int SM_CXHTHUMB = 10;// Width of scroll box on horizontal scroll bar 水平滚动条上滑块的宽度
    const int SM_CXICON = 11;//Width of standard icon 图标宽度
    const int SM_CYICON = 12;//Height of standard icon 图标高度
    const int SM_CXCURSOR = 13;//Width of standard cursor 光标宽度
    const int SM_CYCURSOR = 14;//Height of standard cursor 光标高度
    const int SM_CYMENU = 15;//Height of menu 以像素计算的单个菜单条的高度
    const int SM_CXFULLSCREEN = 16;//Width of client area of maximized window
    const int SM_CYFULLSCREEN = 17;//Height of client area of maximized window
    const int SM_CYKANJIWINDOW = 18;//Height of Kanji window
    const int SM_MOUSEPRESENT = 19;//True is a mouse is present 如果为TRUE或不为0的值则安装了鼠标,否则没有安装。
    const int SM_CYVSCROLL = 20;//Height of arrow in vertical scroll bar
    const int SM_CXHSCROLL = 21;//Width of arrow in vertical scroll bar
    const int SM_DEBUG = 22;//True if deugging version of windows is running
    const int SM_SWAPBUTTON = 23;//True if left and right buttons are swapped.
    const int SM_CXMIN = 28;//Minimum width of window
    const int SM_CYMIN = 29;//Minimum height of window
    const int SM_CXSIZE = 30;//Width of title bar bitmaps
    const int SM_CYSIZE = 31;//height of title bar bitmaps
    const int SM_CXMINTRACK = 34;//Minimum tracking width of window
    const int SM_CYMINTRACK = 35;//Minimum tracking height of window
    const int SM_CXDOUBLECLK = 36;//double click width
    const int SM_CYDOUBLECLK = 37;//double click height
    const int SM_CXICONSPACING = 38;//width between desktop icons
    const int SM_CYICONSPACING = 39;//height between desktop icons
    const int SM_MENUDROPALIGNMENT = 40;//Zero if popup menus are aligned to the left of the memu bar item. True if it is aligned to the right.
    const int SM_PENWINDOWS = 41;//The handle of the pen windows DLL if loaded.
    const int SM_DBCSENABLED = 42;//True if double byte characteds are enabled
    const int SM_CMOUSEBUTTONS = 43;//Number of mouse buttons.
    const int SM_CMETRICS = 44;//Number of system metrics
    const int SM_CLEANBOOT = 67;//Windows 95 boot mode. 0 = normal; 1 = safe; 2 = safe with network
    const int SM_CXMAXIMIZED = 61;//default width of win95 maximised window
    const int SM_CXMAXTRACK = 59;//maximum width when resizing win95 windows
    const int SM_CXMENUCHECK = 71;//width of menu checkmark bitmap
    const int SM_CXMENUSIZE = 54;//width of button on menu bar
    const int SM_CXMINIMIZED = 57;//width of rectangle into which minimised windows must fit.
    const int SM_CYMAXIMIZED = 62;//default height of win95 maximised window
    const int SM_CYMAXTRACK = 60;//maximum width when resizing win95 windows
    const int SM_CYMENUCHECK = 72;//height of menu checkmark bitmap
    const int SM_CYMENUSIZE = 55;//height of button on menu bar
    const int SM_CYMINIMIZED = 58;//height of rectangle into which minimised windows must fit.
    const int SM_CYSMCAPTION = 51;//height of windows 95 small caption
    const int SM_MIDEASTENABLED = 74;//Hebrw and Arabic enabled for windows 95
    const int SM_NETWORK = 63;//bit o is set if a network is present.
    const int SM_SECURE = 44;//True if security is present on windows 95 system
    const int SM_SLOWMACHINE = 73;//true if machine is too slow to run win95.
}
复制代码 SystemMetricsType

  踩过了坑,才知道哪里会有坑……所以,只有分辨率?没有物理尺寸大小???上GetDeviceCaps API。

  2、使用GetDeviceCaps API获取

  使用GetDeviceCaps API时,需要传入一个句柄,需要使用GetDC API,但是……GetDC和ReleaseDC两个API是成对出现的,必须要释放句柄,否则容易造成内存泄漏。

复制代码
 /// <summary>
 /// 获取DC句柄
 /// </summary>
 [DllImport("user32.dll")]
 static extern IntPtr GetDC(IntPtr hdc);
 /// <summary>
 /// 释放DC句柄
 /// </summary>
 [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
 static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
 /// <summary>
 /// 获取句柄指定的数据
 /// </summary>
 [DllImport("gdi32.dll")]
 static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
复制代码

  以下是使用上述API获取屏幕尺寸的示例代码,不知道怎么用的可以看看。但是这个API获取的是当前屏幕的尺寸……

复制代码
class MonitorHelper
{
    /// <summary>
    /// 获取DC句柄
    /// </summary>
    [DllImport("user32.dll")]
    static extern IntPtr GetDC(IntPtr hdc);
    /// <summary>
    /// 释放DC句柄
    /// </summary>
    [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
    static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc);
    /// <summary>
    /// 获取句柄指定的数据
    /// </summary>
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

    /// <summary>
    /// 获取分辨率
    /// </summary>
    /// <returns></returns>
    public static Size GetResolution()
    {
        Size size = new Size();
        IntPtr hdc = GetDC(IntPtr.Zero);
        size.Width = GetDeviceCaps(hdc, DeviceCapsType.DESKTOPHORZRES);
        size.Height = GetDeviceCaps(hdc, DeviceCapsType.DESKTOPVERTRES);
        ReleaseDC(IntPtr.Zero, hdc);
        return size;
    }
    /// <summary>
    /// 获取屏幕物理尺寸(mm,mm)
    /// </summary>
    /// <returns></returns>
    public static Size GetScreenSize()
    {
        Size size = new Size();
        IntPtr hdc = GetDC(IntPtr.Zero);
        size.Width = GetDeviceCaps(hdc, DeviceCapsType.HORZSIZE);
        size.Height = GetDeviceCaps(hdc, DeviceCapsType.VERTSIZE);
        ReleaseDC(IntPtr.Zero, hdc);
        return size;
    }

    /// <summary>
    /// 获取屏幕的尺寸---inch
    /// </summary>
    /// <returns></returns>
    public static float GetScreenInch()
    {
        Size size = GetScreenSize();
        double inch = Math.Round(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / 25.4, 1);
        return (float)inch;
    }
}
复制代码 MonitorHelper

  GetDeviceCaps的第二个参数,值可以是:

复制代码
/// <summary>
/// GetDeviceCaps 的 nidex值
/// </summary>
class DeviceCapsType
{
    const int DRIVERVERSION = 0;
    const int TECHNOLOGY = 2;
    const int HORZSIZE = 4;//以毫米为单位的显示宽度
    const int VERTSIZE = 6;//以毫米为单位的显示高度
    const int HORZRES = 8;
    const int VERTRES = 10;
    const int BITSPIXEL = 12;
    const int PLANES = 14;
    const int NUMBRUSHES = 16;
    const int NUMPENS = 18;
    const int NUMMARKERS = 20;
    const int NUMFONTS = 22;
    const int NUMCOLORS = 24;
    const int PDEVICESIZE = 26;
    const int CURVECAPS = 28;
    const int LINECAPS = 30;
    const int POLYGONALCAPS = 32;
    const int TEXTCAPS = 34;
    const int CLIPCAPS = 36;
    const int RASTERCAPS = 38;
    const int ASPECTX = 40;
    const int ASPECTY = 42;
    const int ASPECTXY = 44;
    const int SHADEBLENDCAPS = 45;
    const int LOGPIXELSX = 88;//像素/逻辑英寸(水平)
    const int LOGPIXELSY = 90; //像素/逻辑英寸(垂直)
    const int SIZEPALETTE = 104;
    const int NUMRESERVED = 106;
    const int COLORRES = 108;
    const int PHYSICALWIDTH = 110;
    const int PHYSICALHEIGHT = 111;
    const int PHYSICALOFFSETX = 112;
    const int PHYSICALOFFSETY = 113;
    const int SCALINGFACTORX = 114;
    const int SCALINGFACTORY = 115;
    const int VREFRESH = 116;
    const int DESKTOPVERTRES = 117;//垂直分辨率
    const int DESKTOPHORZRES = 118;//水平分辨率
    const int BLTALIGNMENT = 119;
}
复制代码 GetDeviceCaps 的 nIdex值

 

 

2024-11-01 15:51:25【出处】:https://www.cnblogs.com/pilgrim/p/15115925.html

=======================================================================================

标签:IntPtr,const,C#,Height,int,API,SM,注册表
From: https://www.cnblogs.com/mq0036/p/18520416

相关文章

  • AGC 杂题
    AGC029CLexicographicconstraints有\(n\)个字符串,现在告知它们的长度\(a_i\),求使得\(\foralli\in[1,n),s_i<s_{i+1}\)的最小字符集大小。\(n\le2\times10^5,a_i\le10^9\)二分字符集大小\(|\Sigma|\),分类讨论,设起始字符为a:\(a_i<a_{i+1}\):显然\(s_{i+1}\leftarr......
  • 开发 react 技术栈的前台项目,选用 semantic-ui-react 组件库是否是较好的选择
    在前端开发中,合适的UI组件库的选择至关重要,它能在保证交互和视觉一致性的同时,大大提升开发效率。Semantic-UI-React是React技术栈中备受关注的UI组件库之一,以其丰富的组件和友好的API受到了许多开发者的欢迎。然而,是否选择它作为项目的UI组件库需结合多个因素综合考虑......
  • UNIVERSITY OFLIVERPOOLDepartment of Electrical Engineering and Electronics
    UNIVERSITYOFLIVERPOOLDepartmentofElectricalEngineeringandElectronicscontactmeonhelp-assignmentcontactmeonhelp-assignmentcontactmeonhelp-assignmentAssignmentOverviewInstantiationandmanipulationofgeometricalobjectsissignificant......
  • BFS(Breath First Search 广度优先搜索)
    @目录一、知识及框架二、案例说明案例1:使用bfs计算二叉树的最小高度案例2:解开密码锁的最少次数,要求:请写一个算法,初始状态为0000,拨出target的最少次数,其中避免出现deadends中的包含的任意一个死亡密码,如果永远无法拨出target,则返回-1本人其他文章链接一、知识及框架BFS算法都是......
  • Visual Studio Code(VSCode)中设置中文界面
    在VisualStudioCode(VSCode)中设置中文界面,你可以采用以下几种方法,以下是详细步骤:方法一:通过设置菜单设置中文打开VSCode:首先,确保你已经打开了VSCode软件。进入设置:点击菜单栏中的“文件”(File)选项。在下拉菜单中选择“首选项”(Preferences)。点击“设置”(Settings)。搜索并设置语......
  • 批量下载文件的方法解析:为什么forEach不行,而for of却能成功?
    在日常开发中,我们经常需要处理批量下载文件的需求。本文将介绍一种批量下载文件的方法,并分析为什么在使用JavaScript进行批量操作时,forEach循环无法成功,而forof循环却能顺利完成。一、批量下载文件的方法在实现批量下载文件的功能时,我们可以采用以下步骤:获取需要下载的文......
  • SpringBoot 快速实现 api 加密!so easy~
    SpringBoot快速实现api加密!soeasy~项目介绍什么是RSA加密举个栗子第一个场景第二个场景加密实战实战准备新建一个springboot项目引入maven依来启动类Application中添加@EnableSecurity注解在application.yml或者application.properties中添加RSA公钥及私钥对Control......
  • 【C++】——高效构建与优化二叉搜索树
    活着就意味必须要做点什么,请好好努力。——村上春树《地下》目录1、二叉搜索树BST1.1什么是二叉搜索树1.2BST的性能功能分析2、二叉搜索树的实现2.1BST框架2.2BST插入2.3BST搜索2.4BST删除2.5BST细节问题3、二叉搜索树遍历3.1中序遍历3.2前序遍历3.3......
  • ABC 杂题
    ABC186EThrone有\(n\)个圆形排列的椅子,一开始你在\(s+1\)上,每次可以向右移动\(k\)个位置,求移动到\(1\)的最小步数,或报告无解。\(2\len,k\le10^9\)很容易想到构造方程:\[s+qk\equiv0\pmodn\]\[q\equiv(n-s)k^{-1}\pmodn\]直接exgcd求逆元,算出在\([1,n-1]\)......
  • NVR接入录像回放平台EasyCVR私有化部署视频平台智慧农田可视化视频监控方案
    一、背景需求科技进步正推动着智慧农业成为现代农业的核心趋势。智慧农田作为智慧农业的关键组成部分,通过集成尖端视频监控技术和智能化管理工具,实现了农业生产的精细化和高效率管理。NVR接入录像回放平台EasyCVR,作为一个功能全面的综合视频监控管理平台,为智慧农田的发展提供了坚......