zoukankan      html  css  js  c++  java
  • C# 获取显示器的物理尺寸或分辨率

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

      获取显示器的尺寸,有两种方法。第一种是通过查询注册表中,存储的指定显示器的相关信息;第二种是通过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_MACHINESYSTEMControlSet001Enum" + 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值
    I travel alone,not to be alone.
  • 相关阅读:
    键盘过滤驱动
    多线程和多进程的差别(小结)
    Android UI设计规则
    怎样使用SetTimer MFC 够具体
    Chord算法(原理)
    POJ 1384 Piggy-Bank 背包DP
    Bulk Insert命令具体
    hibernate官方新手教程 (转载)
    教你用笔记本破解无线路由器password
    转换流--OutputStreamWriter类与InputStreamReader类
  • 原文地址:https://www.cnblogs.com/pilgrim/p/15115925.html
Copyright © 2011-2022 走看看