zoukankan      html  css  js  c++  java
  • 【C#】获取电脑DPI

    public static class DPIGeter
        {
            /// <summary>
            /// 获取DPI
            /// </summary>
            /// <param name="dpix"></param>
            /// <param name="dpiy"></param>
            public static void GetDPI(ref float dpix, ref float dpiy)
            {
                SetProcessDPIAware();//此处会忽视系统DWM虚拟化,不建议使用
                IntPtr screenDC = GetDC(IntPtr.Zero);
                dpix = GetDeviceCaps(screenDC, LOGPIXELSX);
                dpiy = GetDeviceCaps(screenDC, LOGPIXELSY);
                ReleaseDC(IntPtr.Zero, screenDC);
            }
            /// <summary>
            /// 获取DPI缩放比例
            /// </summary>
            /// <param name="dpiscalex"></param>
            /// <param name="dpiscaley"></param>
            public static void GetDPIScale(ref float dpiscalex, ref float dpiscaley)
            {
                int x = GetSystemMetrics(SM_CXSCREEN);
                int y = GetSystemMetrics(SM_CYSCREEN);
                IntPtr hdc = GetDC(IntPtr.Zero);
                int w = GetDeviceCaps(hdc, DESKTOPHORZRES);
                int h = GetDeviceCaps(hdc, DESKTOPVERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                dpiscalex = (float)w / x;
                dpiscaley = (float)h / y;
            }
            [DllImport("user32.dll")]
            static extern IntPtr GetDC(IntPtr ptr);
    
            [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
    
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateDC(
            string lpszDriver, // driver name
            string lpszDevice, // device name
            string lpszOutput, // not used; should be NULL
            Int64 lpInitData // optional printer data
            );
    
            [DllImport("gdi32.dll")]
            public static extern int GetDeviceCaps(
            IntPtr hdc, // handle to DC
            int nIndex // index of capability
            );
    
            [DllImport("user32.dll")]
            internal static extern bool SetProcessDPIAware();
    
            [DllImport("user32")]
            public static extern int GetSystemMetrics(
            int nIndex
            );
    
            [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr GetDesktopWindow();
    
            [DllImport("user32.dll")]
            public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);
    
            public struct Rect
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }
    
            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;
            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.
        }
    附:
     SetProcessDPIAware 和 IsProcessDPIAware , 通过调用SetProcessDPIAware , 我们告诉系统不要对我们的程序进行DWM虚拟化。
    这里还有特殊情况也提一下: 我们在高DPI下通过窗口句柄取到的坐标信息是和目标程序是否支持DWM虚拟化相关联的, 我们对支持DWM虚拟化的程序窗口调用GetWindowRect, 取到的坐标也是经过DWM缩放后的坐标; 对禁用DWM虚拟化程序的窗口调用GetWindowRect, 取到的坐标则是没有经过缩放的原始坐标。

     最后我们再讨论下Win8.1 对高DPI的支持, WIn8.1对高DPi以3种方式支持 Process_DPI_Awareness : 
    typedef enum _Process_DPI_Awareness { 
      Process_DPI_Unaware            = 0,
      Process_System_DPI_Aware       = 1,
      Process_Per_Monitor_DPI_Aware  = 2
    } Process_DPI_Awareness;
    下面我们依次讨论这3种方式: 

    第一种Unaware, 该种方式是告诉系统, 我的程序不支持DPI aware, 请通过DWM虚拟化帮我们实现。 该方式和上面Win7/Win8对高DPI的支持的实现基本一样,主要区别是它通过GetWindowRect取到的坐标都是经过DWM缩放后的, 无论对方窗口是不是支持DWM虚拟化。
     
    第二种方式是System DPI aware, 该方式下告诉系统, 我的程序会在启动的显示器上自己支持DPI aware, 所以不需要对我进行DWM 虚拟化。 但是当我的程序被拖动到其他DPI不一样的显示器时, 请对我们先进行system DWM虚拟化缩放。
     
    第三种方式是Per Monitor DPI aware, 该方式是告诉系统, 请永远不要对我进行DWM虚拟化,我会自己针对不同的Monitor的DPi缩放比率进行缩放。
     
  • 相关阅读:
    Floyd判圈算法 Floyd Cycle Detection Algorithm
    最优化问题 Optimization Problems & 动态规划 Dynamic Programming
    自平衡二叉搜索树
    树 & 二叉树
    数根
    二叉搜索树BST
    K-Means & Sequential Leader Clustering
    KMP算法
    递归问题的时间复杂度分析
    人工神经网络 Artificial Neural Network
  • 原文地址:https://www.cnblogs.com/mqxs/p/7495690.html
Copyright © 2011-2022 走看看