动态获取当前系统的缩放比例dpi(windows)

本文介绍了在程序中如何动态获取Windows系统DPI和屏幕缩放比例,以解决元素坐标计算在分辨率或缩放变化时的偏差问题。首先,通过`GetDpiForWindow` API获取桌面窗口的DPI,此方法适用于大部分情况,但需注意某些用户可能有不同的桌面className。其次,利用`GetDeviceCaps`计算可视桌面与真实像素的比例,以获取缩放系数。这两种方法对于动态适应分辨率和缩放变化的软件开发非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题场景:近期项目中要解决元素坐标计算在桌面分辨率/缩放动态改变时有偏差的问题

测试猜想是动态改变分辨率/缩放之后坐标计算没有相应改变

之前计算dpi的方式为

        /// <summary>
        /// 当前系统DPI_X 大小 一般为96
        /// </summary>
        public static int DpiX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }

该方式能得出屏幕dpi但是设置屏幕缩放改变之后,再次运行只会得到初始的dpi。即无法动态获取当前的dpi。

经过一番查找与跟同事交流得到两个可以动态获取dpi缩放的方式。

1.通过获取桌面的dpi,来确定为当前dpi。

        /// <summary>
        /// 获取动态的系统DPI_X 大小  防止分辨率改变后拿不到实际改变之后的dpi
        /// </summary>
        public static int DynamicDpiX
        {
            get
            {
                IntPtr hd1 = FindWindow("Progman", "Program Manager");
                int DpiX = GetDpiForWindow(hd1);
                return DpiX;
            }
        }

该方法获取桌面的句柄,然后调用API GetDpiForWindow 来获取当前桌面的dpi。经过测试,满足动态获取的要求。 但是需要注意一点,有的用户电脑,桌面的class Name可能不叫Progman, 而是WorkerW,所以可以加个对WorkerW的检测。

该方式是从网上一个C++解决方案改写的。关于动态获取系统DPI问题_Greless的后花园-优快云博客1.获取系统DPI的方式有很多,但都有一个问题,获取的DPI可能回修改前的DPI#include <iostream> #include <Windows.h>#pragma comment(lib,"Gdi32.lib")#pragma comment(lib,"User32.lib")int main(void) {//HWND hd = GetDesktopWindow();HWND hd1 = FindWindow(NULL,L"Program Mhttps://blog.youkuaiyun.com/greless/article/details/115070716

2.另外跟同事交流获取另外一种解决方式: 

        /// <summary>
        /// 获取宽度缩放百分比
        /// </summary>
        public static float ScaleX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int t = GetDeviceCaps(hdc, DESKTOPHORZRES);
                int d = GetDeviceCaps(hdc, HORZRES);
                float ScaleX = ((float)t) / d;
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleX;
            }
        }

 这种是获取缩放系数,即dpi/96. 

原理是用可视桌面的像素(DESKTOPHORZRES)除以真实像素(HORZRES)来获得比例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值