WPF:如何同时处理不同的屏幕分辨率“DPI”?

时间:2018-06-08 02:17:10

标签: c# .net wpf resolution dpi

我使用一些获取监视器DPI的代码,然后使用它绘制一些WPF组件。

但问题是当我有两个不同分辨率的屏幕“DPI”时,我会说投影机连接成扩展屏幕到你的笔记本电脑,事情变得非常混乱,组件位置变得非常奇怪,如何处理这种情况? / p>

不确定代码是否有用,但在此处

    var dpi = GetDPI((int)Application.Current.MainWindow.Top, (int)Application.Current.MainWindow.Left);

    public static double GetDPI(int left, int top)
    {
        uint dpiX, dpiY;
        GetDpi(new System.Drawing.Point(left, top), DpiType.Effective, out dpiX, out dpiY);

        return GetDPIRate(dpiX);
    }

    public static void GetDpi(System.Drawing.Point point, DpiType dpiType, out uint dpiX, out uint dpiY)
    {
        var mon = MonitorFromPoint(point, 2);
        if (IsWindows7())
        {
            Graphics g = Graphics.FromHwnd(IntPtr.Zero);
            IntPtr desktop = g.GetHdc();

            dpiX = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX);
            dpiY = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSY);
        }
        else
        {
            GetDpiForMonitor(mon, dpiType, out dpiX, out dpiY);
        }
    }

    private static double GetDPIRate(uint dpi)
    {
        return dpi / 96.0;
    }

    public static bool IsWindows7()
    {
        return Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1;
    }

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    public static extern uint GetDeviceCaps(IntPtr hDC, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("User32.dll")]
    private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);

    [DllImport("user32.dll")]
    public static extern bool SystemParametersInfo(int iAction, int iParam, out bool bActive, int iUpdate);

    [DllImport("Shcore.dll")]
    private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);

1 个答案:

答案 0 :(得分:0)

因此,答案取决于很多事情:

1-您可以在项目清单中使用标记,然后由Windows来处理。 2-您可以在任何屏幕上使用一个点来获取该屏幕的DPI 3-同样,如果您使用的是任何Win32控件,可能会造成混乱,因为Win32的dpi识别能力与wpf不同,并且当您使用第一个选项(即该标签)时,它可能会使您拥有的Win32控件混乱

https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context

https://docs.microsoft.com/en-us/windows/desktop/hidpi/declaring-managed-apps-dpi-aware Disable DPI awareness for WPF application