/// <summary> /// Sets the DPI awareness. If not available on the current OS, it falls back to the next possible. /// </summary> /// <returns>true/false - If the process DPI awareness is successfully set, returns true. Otherwise false.</returns> internal static bool SetWinformsApplicationDpiAwareness(HighDpiMode highDpiMode) { CAPS.PROCESS_DPI_AWARENESS dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_DPI_UNINITIALIZED; if (OsVersion.IsWindows10_1703OrGreater) { // SetProcessDpiAwarenessContext needs Windows 10 RS2 and above int rs2AndAboveDpiFlag; switch (highDpiMode) { case HighDpiMode.SystemAware: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; break; case HighDpiMode.PerMonitor: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; break; case HighDpiMode.PerMonitorV2: // Necessary for RS1, since this SetProcessDpiAwarenessContext IS available here. rs2AndAboveDpiFlag = SafeNativeMethods.IsValidDpiAwarenessContext(CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) ? CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 : CAPS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; break; case HighDpiMode.DpiUnawareGdiScaled: // Let's make sure, we do not try to set a value which has been introduced in later Windows releases. rs2AndAboveDpiFlag = SafeNativeMethods.IsValidDpiAwarenessContext(CAPS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED) ? CAPS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED : CAPS.DPI_AWARENESS_CONTEXT_UNAWARE; break; default: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_UNAWARE; break; } return(SafeNativeMethods.SetProcessDpiAwarenessContext(rs2AndAboveDpiFlag)); } else if (OsVersion.IsWindows8_1OrGreater) { // 8.1 introduced SetProcessDpiAwareness switch (highDpiMode) { case HighDpiMode.DpiUnaware: case HighDpiMode.DpiUnawareGdiScaled: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE; break; case HighDpiMode.SystemAware: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; case HighDpiMode.PerMonitor: case HighDpiMode.PerMonitorV2: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE; break; default: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; } return(SafeNativeMethods.SetProcessDpiAwareness(dpiFlag) == CAPS.S_OK); } else { // Vista or higher has SetProcessDPIAware switch (highDpiMode) { case HighDpiMode.DpiUnaware: case HighDpiMode.DpiUnawareGdiScaled: // We can return, there is nothing to set if we assume we're already in DpiUnaware. return(true); case HighDpiMode.SystemAware: case HighDpiMode.PerMonitor: case HighDpiMode.PerMonitorV2: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; } if (dpiFlag == CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE) { return(SafeNativeMethods.SetProcessDPIAware()); } } return(false); }
/// <summary> /// Sets the DPI awareness. If not available on the current OS, it falls back to the next possible. /// </summary> /// <returns>true/false - If the process DPI awareness is successfully set, returns true. Otherwise false.</returns> internal static bool SetWinformsApplicationDpiAwareness(HighDpiMode highDpiMode) { CAPS.PROCESS_DPI_AWARENESS dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_DPI_UNINITIALIZED; // For Windows 10 RS2 and above if (ApiHelper.IsApiAvailable(ExternDll.User32, nameof(SafeNativeMethods.SetProcessDpiAwarenessContext))) { int rs2AndAboveDpiFlag; switch (highDpiMode) { case HighDpiMode.SystemAware: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; break; case HighDpiMode.PerMonitor: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; break; case HighDpiMode.PerMonitorV2: // Necessary for RS1, since this SetProcessDpiAwarenessContext IS available here. rs2AndAboveDpiFlag = SafeNativeMethods.IsValidDpiAwarenessContext(CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) ? CAPS.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 : CAPS.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; break; case HighDpiMode.DpiUnawareGdiScaled: // Let's make sure, we do not try to set a value which has been introduced in later Windows releases. rs2AndAboveDpiFlag = SafeNativeMethods.IsValidDpiAwarenessContext(CAPS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED) ? CAPS.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED : CAPS.DPI_AWARENESS_CONTEXT_UNAWARE; break; default: rs2AndAboveDpiFlag = CAPS.DPI_AWARENESS_CONTEXT_UNAWARE; break; } return(SafeNativeMethods.SetProcessDpiAwarenessContext(rs2AndAboveDpiFlag)); } // For operating systems Windows 8.1 to Windows 10 RS1 version. else if (ApiHelper.IsApiAvailable(ExternDll.ShCore, nameof(SafeNativeMethods.SetProcessDpiAwareness))) { switch (highDpiMode) { case HighDpiMode.DpiUnaware: case HighDpiMode.DpiUnawareGdiScaled: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE; break; case HighDpiMode.SystemAware: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; case HighDpiMode.PerMonitor: case HighDpiMode.PerMonitorV2: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE; break; default: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; } return(SafeNativeMethods.SetProcessDpiAwareness(dpiFlag) == CAPS.S_OK); } // For operating systems windows 7 to windows 8 else if (ApiHelper.IsApiAvailable(ExternDll.User32, nameof(SafeNativeMethods.SetProcessDPIAware))) { switch (highDpiMode) { case HighDpiMode.DpiUnaware: case HighDpiMode.DpiUnawareGdiScaled: // We can return, there is nothing to set if we assume we're already in DpiUnaware. return(true); case HighDpiMode.SystemAware: case HighDpiMode.PerMonitor: case HighDpiMode.PerMonitorV2: dpiFlag = CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE; break; } if (dpiFlag == CAPS.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE) { return(SafeNativeMethods.SetProcessDPIAware()); } } return(false); }