| File: MS\Internal\WindowsRuntime\Windows\UI\ViewManagement\UISettings.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.IO; using System.Runtime.InteropServices; using System.Windows.Media; namespace MS.Internal.WindowsRuntime { namespace Windows.UI.ViewManagement { internal class UISettings : IDisposable { private readonly bool _isSupported; private UISettingsRCW.IUISettings3 _uisettings; private static readonly Color _fallbackAccentColor = Color.FromArgb(0xff, 0x00, 0x78, 0xd4); private Color _accentColor, _accentLight1, _accentLight2, _accentLight3; private Color _accentDark1, _accentDark2, _accentDark3; private bool _useFallbackColor = false; internal UISettings() { _isSupported = false; try { _uisettings = GetWinRTInstance() as UISettingsRCW.IUISettings3; } catch (COMException) { // We don't want to throw any exceptions here. // If we can't get the instance, we will use the default accent color. } if (_uisettings != null) { _isSupported = true; TryUpdateAccentColors(); } } /// <summary> /// Gets the accent color value for the desired color type. /// </summary> /// <returns> /// Returns true if fetching value from UISettings was successful. /// If the fetch fails, we return false and return the default accent color. /// </returns> internal bool TryGetColorValue(UISettingsRCW.UIColorType desiredColor, out Color color) { if(_isSupported) { try { var uiColor = _uisettings.GetColorValue(desiredColor); color = Color.FromArgb(uiColor.A, uiColor.R, uiColor.G, uiColor.B); return true; } catch (COMException) { // We don't want to throw any exceptions here. // If we can't get the instance, we will use the default accent color. } } color = _fallbackAccentColor; return false; } /// <summary> /// Tries to update the accent colors properties. /// If any call to TryGetColorValue fails, we set _useFallbackColor to true. /// After which all the accent values will be the default color. /// This is to ensure that we don't have inconsistent set of accent color values stored. /// </summary> internal void TryUpdateAccentColors() { _useFallbackColor = true; if(_isSupported) { try { if(TryGetColorValue(UISettingsRCW.UIColorType.Accent, out Color systemAccent)) { // For verifying if any of the calls to TryGetColorValue fails. bool result = true; if(_accentColor != systemAccent) { result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentLight1, out _accentLight1); result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentLight2, out _accentLight2); result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentLight3, out _accentLight3); result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentDark1, out _accentDark1); result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentDark2, out _accentDark2); result &= TryGetColorValue(UISettingsRCW.UIColorType.AccentDark3, out _accentDark3); _accentColor = systemAccent; } // If result is false, hence atleast one call, use fallback values. _useFallbackColor = !result; } } catch { // We don't want to throw any exceptions here. // If we can't get any one of the color values, we will use the default accent color. } } } /// <summary> /// Gets the WinRT instance of UISettings. /// </summary> private static object GetWinRTInstance() { object winRtInstance = null; try { winRtInstance = UISettingsRCW.GetUISettingsInstance(); } catch (Exception e) when (e is TypeLoadException || e is FileNotFoundException) { winRtInstance = null; } return winRtInstance; } #region Color Properties internal Color AccentColor => _useFallbackColor ? _fallbackAccentColor : _accentColor; internal Color AccentLight1 => _useFallbackColor ? _fallbackAccentColor : _accentLight1; internal Color AccentLight2 => _useFallbackColor ? _fallbackAccentColor : _accentLight2; internal Color AccentLight3 => _useFallbackColor ? _fallbackAccentColor : _accentLight3; internal Color AccentDark1 => _useFallbackColor ? _fallbackAccentColor : _accentDark1; internal Color AccentDark2 => _useFallbackColor ? _fallbackAccentColor : _accentDark2; internal Color AccentDark3 => _useFallbackColor ? _fallbackAccentColor : _accentDark3; #endregion #region IDisposable private bool _disposed = false; ~UISettings() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!_disposed) { if (_uisettings != null) { try { // Release the _uiSettings instance here Marshal.ReleaseComObject(_uisettings); } catch { // Don't want to raise any exceptions in a finalizer, eat them here } _uisettings = null; } _disposed = true; } } #endregion } } }