internal static void InitializeDpiHelperForWinforms() { if (s_isInitializeDpiHelperForWinforms) { return; } // initialize shared fields Initialize(); if (OsVersion.IsWindows10_1607OrGreater) { // We are on Windows 10/1603 or greater, but we could still be DpiUnaware or SystemAware, so let's find that out... IntPtr hProcess = Kernel32.OpenProcess( Kernel32.ProcessAccessOptions.QUERY_INFORMATION, BOOL.FALSE, Kernel32.GetCurrentProcessId()); SHCore.GetProcessDpiAwareness(hProcess, out SHCore.PROCESS_DPI_AWARENESS processDpiAwareness); // Only if we're not, it makes sense to query for PerMonitorV2 awareness from now on, if needed. if (!(processDpiAwareness == SHCore.PROCESS_DPI_AWARENESS.UNAWARE || processDpiAwareness == SHCore.PROCESS_DPI_AWARENESS.SYSTEM_AWARE)) { s_doesNeedQueryForPerMonitorV2Awareness = true; } } if (IsScalingRequired || s_doesNeedQueryForPerMonitorV2Awareness) { s_isScalingRequirementMet = true; } s_isInitializeDpiHelperForWinforms = true; }
/// <summary> /// Gets the DPI awareness. /// </summary> /// <returns>The thread's/process' current HighDpi mode</returns> internal static HighDpiMode GetWinformsApplicationDpiAwareness() { // For Windows 10 RS2 and above if (OsVersion.IsWindows10_1607OrGreater) { DpiAwarenessContext dpiAwareness = CommonUnsafeNativeMethods.GetThreadDpiAwarenessContext(); if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) { return(HighDpiMode.SystemAware); } if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE)) { return(HighDpiMode.DpiUnaware); } if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { return(HighDpiMode.PerMonitorV2); } if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) { return(HighDpiMode.PerMonitor); } if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) { return(HighDpiMode.DpiUnawareGdiScaled); } } else if (OsVersion.IsWindows8_1OrGreater) { SHCore.GetProcessDpiAwareness(IntPtr.Zero, out SHCore.PROCESS_DPI_AWARENESS processDpiAwareness); switch (processDpiAwareness) { case SHCore.PROCESS_DPI_AWARENESS.UNAWARE: return(HighDpiMode.DpiUnaware); case SHCore.PROCESS_DPI_AWARENESS.SYSTEM_AWARE: return(HighDpiMode.SystemAware); case SHCore.PROCESS_DPI_AWARENESS.PER_MONITOR_AWARE: return(HighDpiMode.PerMonitor); } } else { // Available on Vista and higher return(User32.IsProcessDPIAware().IsTrue() ? HighDpiMode.SystemAware : HighDpiMode.DpiUnaware); } // We should never get here, except someone ported this with force to < Windows 7. return(HighDpiMode.DpiUnaware); }
private static bool GetPerMonitorAware() { if (!OsVersion.IsWindows10_1607OrGreater) { return(false); } HRESULT result = SHCore.GetProcessDpiAwareness( IntPtr.Zero, out SHCore.PROCESS_DPI_AWARENESS processDpiAwareness); Debug.Assert(result.Succeeded(), $"Failed to get ProcessDpi HRESULT: {result}"); Debug.Assert(Enum.IsDefined(typeof(SHCore.PROCESS_DPI_AWARENESS), processDpiAwareness)); return(result.Succeeded() && processDpiAwareness switch { SHCore.PROCESS_DPI_AWARENESS.UNAWARE => false, SHCore.PROCESS_DPI_AWARENESS.SYSTEM_AWARE => false, SHCore.PROCESS_DPI_AWARENESS.PER_MONITOR_AWARE => true, _ => true });