File: MS\Internal\WindowsRuntime\Windows\UI\ViewManagement\UISettings.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore)
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using MS.Internal.PresentationCore.WindowsRuntime;
 
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
 
            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
        }
    }
}