WPF: Как обрабатывать разные разрешения экрана «DPI» одновременно? - PullRequest
0 голосов
/ 08 июня 2018

Я использую некоторый код, который получает разрешение монитора, затем я рисую некоторые компоненты WPF, используя его.

, но проблема, когда у меня есть 2 экрана с различным разрешением «DPI», я бы сказал, как проектор, подключенный какрасширенный экран на вашем ноутбуке, вещи становятся действительно запутанными, а позиции компонентов становятся действительно странными, как справиться с таким делом?

Не уверен, поможет ли код, но здесь он

    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 голосов
/ 07 августа 2018

Итак, ответ зависит от многих вещей:

1 - Вы можете использовать тег в манифесте проекта и позволить окнам позаботиться об этом.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 Отключить поддержку DPI для приложения WPF

...