首页 > 编程语言 >C# 获取系统DPI缩放比例以及分辨率大小

C# 获取系统DPI缩放比例以及分辨率大小

时间:2023-04-26 11:24:02浏览次数:49  
标签:IntPtr 缩放 C# 获取 分辨率 int Zero hdc DPI

一般方法

System.Windows.Forms.Screen

// 获取当前主屏幕分辨率
int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;

// 获取指定屏幕分辨率
Screen secondaryScreen = Screen.AllScreens[1];
int secondaryScreenWidth = secondaryScreen.Bounds.Width;
int secondaryScreenHeight = secondaryScreen.Bounds.Height;

System.Windows.SystemParameters

// 获取当前主屏幕分辨率
double screenWidth = SystemParameters.PrimaryScreenWidth;
double screenHeight = SystemParameters.PrimaryScreenHeight;

// 获取所有屏幕的分辨率
double virtualScreenWidth = SystemParameters.VirtualScreenWidth;
double virtualScreenHeight = SystemParameters.VirtualScreenHeight;

虚拟屏幕是指所有物理屏幕组合成的逻辑屏幕,可以用于跨越多个物理屏幕显示应用程序。

这两个方法都可以在正常情况下获取到屏幕的分辨率 - 当桌面缩放比例不是 100% 的时候获取到的分辨率就是“真实”的分辨率了,而是按缩放比例调整以后屏幕显示的内容的宽度和高度。

Windows API

一开始写了个只获取 DPI 缩放比例的,然后自己手动乘一下,但是调用System.Windows.Interop的时候在同事电脑上找不到这个命名空间,不知道什么原因,后来找到了一篇类似功能的文章,微调了一下:

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ScreenDPIHelper
{
    public class ScreenDPIHelper
    {
        #region Win32 API

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr ptr);
        [DllImport("gdi32.dll")]
        static extern int GetDeviceCaps(
        IntPtr hdc, // handle to DC
        int nIndex // index of capability
        );
        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

        #endregion

        #region DeviceCaps - 设备属性 常量

        const int HORZRES = 8;
        const int VERTRES = 10;
        const int LOGPIXELSX = 88;
        const int LOGPIXELSY = 90;
        const int DESKTOPVERTRES = 117;
        const int DESKTOPHORZRES = 118;

        #endregion

        #region 属性

        // 获取屏幕分辨率当前物理大小
        public static Size WorkingArea
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                Size size = new Size();
                size.Width = GetDeviceCaps(hdc, HORZRES);
                size.Height = GetDeviceCaps(hdc, VERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }
        // 当前系统DPI_X 大小 一般为96
        public static int DpiX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }
        // 当前系统DPI_Y 大小 一般为96
        public static int DpiY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }
        // 获取真实设置的桌面分辨率大小
        public static Size DesktopResolution
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                Size size = new Size();
                size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES);
                size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }
        // 获取宽度缩放百分比
        public static float ScaleX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleX;
            }
        }
        // 获取高度缩放百分比
        public static float ScaleY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleY;
            }
        }

        #endregion
    }
}

这个类用到了user32.dllgdi32.dll这两个Win32动态链接库,并调用了其中的函数。如:

  • GetDC: 该函数返回指定窗口客户区域或屏幕的设备上下文(DC)。
  • ReleaseDC: 该函数释放由GetDC函数获得的指定设备上下文(DC)。
  • GetDeviceCaps: 该函数检索指定设备的某些功能,如分辨率,颜色深度,打印机输出分辨率等。

定义的常量参数分别为:

  • HORZRES:水平方向分辨率。
  • VERTRES:垂直方向分辨率。
  • LOGPIXELSX:水平方向 DPI。
  • LOGPIXELSY:垂直方向 DPI。
  • DESKTOPVERTRES:真实的桌面分辨率的垂直大小。
  • DESKTOPHORZRES:真实的桌面分辨率的水平大小。

参数的值是对应参数在 Win32 API 中的索引。

可获取的参数分别是:

  • WorkingArea:获取屏幕分辨率的物理大小,也就是去掉任务栏等占据屏幕空间后的大小。
  • DpiX:获取当前系统水平方向的 DPI ,DPI 是一个表示每英寸点数的度量单位,通常为 96。
  • DpiY:获取当前系统垂直方向的 DPI 。
  • DESKTOP:获取真实的桌面分辨率大小,包括任务栏等占据空间的部分。
  • ScaleX:获取宽度的缩放比例,即当前屏幕的实际宽度与标准宽度(DESKTOPHORZRES)的比值。
  • ScaleY:获取高度的缩放比例,即当前屏幕的实际高度与标准高度(DESKTOPVERTRES)的比值。

参考文档:

平台调用示例

用平台调用封送数据

标识 DLL 中的函数

C# API 获取系统DPI缩放倍数跟分辨率大小

标签:IntPtr,缩放,C#,获取,分辨率,int,Zero,hdc,DPI
From: https://www.cnblogs.com/BoiledYakult/p/17355056.html

相关文章

  • IC99680: SEGMENTATION FAULT AND CRASH DURING DSMSERV FORMAT COMMAND
      APARstatusClosedasprogramerror. ErrordescriptionThedsmservformatprocesscancrashwithasegmentationfaultwheninitiatedbyanadministratorduringmanualinstanceconfiguration.Forexample:$/opt/tivoli/tsm/serv......
  • 机器学习(七):梯度下降解决分类问题——perceptron感知机算法与SVM支持向量机算法进行二
    实验2感知机算法与支持向量机算法一、预备知识1.感知机算法二、实验目的掌握感知机算法的原理及设计;掌握利用感知机算法解决分类问题。三、实验内容设计感知机算法求解,设计SVM算法求解(可调用函数库),请找出支持向量和决策超平面。四、操作方法和实验步骤1.......
  • uniapp 动态修改 css 样式
    css使用var注入变量,达到设置动态样式的需求声明css变量时,变量名前面要加两根连词线(--);变量使用kebab-case命名方式,即--header-color而不是--headerColor;变量名大小写敏感,--header-color和--Header-Color是两个不同的变量名;var()函数用于读取变量。接下来,看......
  • PGSQL系统表之 pg_class 记载表和几乎所有有字段或者是那些类似表的东西
     pg_classpg_class表记载表和几乎所有有字段或者是那些类似表的东西。包括索引(不过还要参阅pg_index)、序列、视图、物化视图、复合类型和一些特殊关系类型;参阅relkind。在下面,当指所有这些对象的时候说"关系"(relations)。不是所有字段对所有关系类型都有意义。表47-11......
  • 【ChatGPT】ChatGPT的部署
    1.模型训练:使用大规模训练数据集对ChatGPT模型进行训练,以提高模型的准确性和适用性。训练好的模型可以保存为一个文件,并用于后续的部署。2.模型转换:由于ChatGPT是基于深度学习框架PyTorch实现的,因此需要将PyTorch模型转换为TensorFlowServing支持的格式。这一步可以使用TensorF......
  • Hugging Face公司介绍
    HuggingFace是一家非常活跃的人工智能创业公司。它拥有一个非常强大并且活跃的人工智能社区。有超过5000多家机构都在HuggingFace的社区发布内容,包括GoogleAI、FacebookAI、微软等。自从2016年成立以来,这家企业经历了5轮融资,总共募集了6000万美金。 那么,这是一家什么样......
  • 关于使用tcpdump命令抓包时网络接口的查询与指定
    第一步:首先可以通过tcpdump命令的--list-interfaces选项,列出系统中的所有网络接口(这个与ipaddr列出的还有略有点点差异)-D--list-interfacesPrintthelistofthenetworkinterfacesavailableonthesystemandonwhichtcpdumpcancapturepackets.......
  • Python的socket编程
    目前处在学习python爬虫的阶段,昨天看到了python的socket模块,分别实现TCP、UDP时间戳回显。1、tcp通信server和client代码#tcpServer.py#!/usr/bin/python#-*-coding:utf-8-*-fromsocketimport*fromtimeimportctimeHOST=''PORT=21156BUFSIZE=1024ADD......
  • f-stack安装测试
    #cloneF-Stackmkdir-p/data/f-stackgitclonehttps://github.com/F-Stack/f-stack.git/data/f-stack#Installlibnuma-devyuminstallnumactl-devel#onCentos#sudoapt-getinstalllibnuma-dev#onUbuntupip3installpyelftools--upgrade#Installp......
  • pid算法函数实现,c语言版
     #include<stdio.h>floatpid(floatsetpoint,floatprocess_variable,floatkp,floatki,floatkd,floatdt,float*integral,float*last_error){//Calculateerrorfloaterror=setpoint-process_variable;//Calculateintegral......