获取鼠标点击屏幕DPI

主窗体DPI、鼠标所在屏幕的DPI

1 开启DPI感知app.manifest

 <!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
      自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
      选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
      在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。    
      将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
	<windowsSettings>
		<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
		<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
		<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
	</windowsSettings>
</application>

2 获取主窗体DPI

private double GetDpiScale()
{
    var mainWindow = Application.Current.MainWindow;
    if (mainWindow == null)  return 1.0;
    var presentationSource = PresentationSource.FromVisual(mainWindow);
    if (presentationSource?.CompositionTarget == null)  return 1.0;
    return presentationSource.CompositionTarget.TransformToDevice.M11;
}

private double GetDpiScale()
{
    //这个是主屏幕的DPI
    using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
    {
        // 获取当前屏幕的DPI
        float dpiX = g.DpiX;
        // 标准DPI是96,计算缩放比例
        return dpiX / 96.0f;
    }
}

3 获取鼠标点击屏幕的DPI

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Service
{
    public class ScreenHelper
    {
        // 导入必要的 Windows API
        [DllImport("user32.dll")]
        private static extern IntPtr MonitorFromPoint(Point pt, uint dwFlags);

        [DllImport("shcore.dll")]
        private static extern int GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY);

        private enum MonitorDpiType
        {
            MDT_EFFECTIVE_DPI = 0,
            MDT_ANGULAR_DPI = 1,
            MDT_RAW_DPI = 2,
            MDT_DEFAULT = MDT_EFFECTIVE_DPI
        }

        // 获取当前鼠标所在屏幕的DPI缩放比例
        public static double GetDpiScaleAtMousePosition()
        {
            // 获取鼠标当前位置
            Point mousePos = Cursor.Position;

            // 获取鼠标所在屏幕的句柄
            IntPtr monitorHandle = MonitorFromPoint(mousePos, 2 /*MONITOR_DEFAULTTONEAREST*/);

            // 获取该屏幕的DPI
            uint dpiX, dpiY;
            if (GetDpiForMonitor(monitorHandle, MonitorDpiType.MDT_EFFECTIVE_DPI, out dpiX, out dpiY) == 0)
            {
                // 计算缩放比例(基于标准96DPI)
                return dpiX / 96.0;
            }

            // 如果API调用失败,回退到主屏幕的DPI
            using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
            {
                return g.DpiX / 96.0;
            }
        }
    }
}

posted on 2025-08-12 17:14  TanZhiWei  阅读(33)  评论(0)    收藏  举报