WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

DisplayInformation throws exception

Open selastingeorge opened this issue 4 years ago • 5 comments

I am working on a .net5 project which uses winrt, I was trying to get the scalefactor from the DisplayInformation Class but calling DisplayInformation.GetForCurrentView() throws exception, is it because core window, core application view is not supported in WPF, it throws an COM exception stating "element not found". Is there any way to overcome this, or should i need to continue with win32 methods itself.

selastingeorge avatar Oct 08 '21 05:10 selastingeorge

@AdamBraden - this should probably go into the Interop bucket.

@Extrimis - which specific property on DisplayInformation were you looking for? Maybe @zhuman can advise on other means to get the Scale Factor from a .NET5 WPF project?

jonwis avatar Oct 12 '21 05:10 jonwis

I Was looking for the ResolutionScale Property from DisplayInformation Class, I Was trying to resize the application window automatically to the screen resolution so in devices which uses 125% text scaling the value of SystemParameters.VirtualScreenWidth and SystemParameters.VirtualScreenHeight seems to give wrong values, currently i have a got a solution from WPF, most of the parts of my application is built using WinRT so i am looking for an alternate code using WinRT. Here is the current code

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using System.Windows.Media;
using static FluentCompositor.Interop.NativeMethods;

namespace FluentCompositor.Utilities
{
    internal static class DpiHelper
    {
        private static readonly double dpi = 96.0;

        internal static uint GetWindowDpi(IntPtr hwnd)
        {
            return GetDpiForWindow(hwnd);
        }

        internal static double GetCompositionTargetDpi(CompositionTarget compositionTarget)
        {
            return dpi * compositionTarget.TransformFromDevice.M11;
        }

        internal static double GetScalefactor(HwndSource source)
        {
            return GetWindowDpi(source.Handle) / GetCompositionTargetDpi(source.CompositionTarget);
        }
    }
}

The GetScalefactor() function provides me a value that i can multiply with the SystemParameters.VirtualScreenWidth or SystemParameters.VirtualScreenHeight, which gives me the exact screen resolution

selastingeorge avatar Oct 12 '21 05:10 selastingeorge

Since there is no more CoreWindow, any GetForCurrent* methods won't work. I believe there is a note about this in the docs but maybe worth making it more visible (e.g. can we detour those methods to crash with an appropriate error message?)

asklar avatar Oct 18 '21 17:10 asklar

As of Insider builds from the last few months, we've added a new IDisplayInformationStaticsInterop interface that you can use in your app to create a DisplayInformation instance for your HWND. We recommend using its GetForWindow method with an HWND if possible, since that gets you events for when your window moves around automatically. If you have a scenario where you don't use an HWND and you manage monitor placement directly, there is also a GetForMonitor API on this interface that takes an HMONITOR.

zhuman avatar Jul 07 '22 08:07 zhuman

@zhuman That's not particularly helpful for Windows App SDK devs that are targeting 17763+. Maybe the team could consider undocking that impl. and putting it into the Windows App SDK?

riverar avatar Jul 07 '22 16:07 riverar