How to get the current color theme of Visual Studio

I create my own IntelliSense Presenter, since Visual Studio2012 supports the theme change, so I want my presenter background color to be able to automatically change when the theme has changed. Is there a way to track a theme change event or get the current color theme of Visual Studio?

+7
source share
3 answers

Yes it is possible. I had to solve a similar problem with one of my extensions ... The current topic is stored in the Windows registry; so I applied the following utility class.

public enum VsTheme { Unknown = 0, Light, Dark, Blue } public class ThemeUtil { private static readonly IDictionary<string, VsTheme> Themes = new Dictionary<string, VsTheme>() { { "de3dbbcd-f642-433c-8353-8f1df4370aba", VsTheme.Light }, { "1ded0138-47ce-435e-84ef-9ec1f439b749", VsTheme.Dark }, { "a4d6a176-b948-4b29-8c66-53c97a1ed7d0", VsTheme.Blue } }; public static VsTheme GetCurrentTheme() { string themeId = GetThemeId(); if (string.IsNullOrWhiteSpace(themeId) == false) { VsTheme theme; if (Themes.TryGetValue(themeId, out theme)) { return theme; } } return VsTheme.Unknown; } public static string GetThemeId() { const string CategoryName = "General"; const string ThemePropertyName = "CurrentTheme"; string keyName = string.Format(@"Software\Microsoft\VisualStudio\11.0\{0}", CategoryName); using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName)) { if (key != null) { return (string)key.GetValue(ThemePropertyName, string.Empty); } } return null; } } 

Good; it just helps to determine the current settings ... listening to the subject of the modified notification is a bit more complicated. After downloading the package, you should get an IVsShell instance through the DTE; If you have this object, you can use the AdviceBroadcastMessages method to subscribe to event notifications. You must provide an object of type IVsBroadcastMessageEvents ...

I do not want to publish the entire implementation, but the following lines may illustrate the key scenario ...

 class VsBroadcastMessageEvents : IVsBroadcastMessageEvent { int IVsBroadcastMessageEvent.OnBroadcastMessage(uint msg, IntPtr wParam, IntPtr lParam) { const uint WM_SYSCOLORCHANGE = 0x15; if (msg == WM_SYSCOLORCHANGE) { // obtain current theme from the Registry and update any UI... } } } 

Consider implementing IDisposable for this type to be able to unsubscribe from the event source when the package is unloaded.

Here's how I sign up for event notifications ...

 class ShellService { private readonly IVsShell shell; private bool advised; public ShellService(IVsShell shellInstance) { this.shell = shellInstance; } public void AdviseBroadcastMessages(IVsBroadcastMessageEvents broadcastMessageEvents, out uint cookie) { cookie = 0; try { int r = this.shell.AdviseBroadcastMessages(broadcastMessageEvents, out cookie); this.advised = (r == VSConstants.S_OK); } catch (COMException) { } catch (InvalidComObjectException) { } } public void UnadviseBroadcastMessages(uint cookie) { ... } } 

Save cookie value; you will need it to unsubscribe successfully.

Hope that helps (-:

+13
source

For VS 2015, this has changed, @Matze's solution still works, but you need to update the GetThemeId () function to check the version, and if it is 14.0 (VS2015) it looks in a different registry location. The way to save the value has also changed, it is still a string, but now it contains other values, separated by the "*" symbol. The guid topic is the last value in the list.

 if (version == "14.0") { string keyName = string.Format(@"Software\Microsoft\VisualStudio\{0}\ApplicationPrivateSettings\Microsoft\VisualStudio", version); using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName)) { if (key != null) { var keyText = (string)key.GetValue("ColorTheme", string.Empty); if (!string.IsNullOrEmpty(keyText)) { var keyTextValues = keyText.Split('*'); if (keyTextValues.Length > 2) { return keyTextValues[2]; } } } } return null; } 
+7
source

I just wanted to put an update in case anyone else came .. @Matze and @Frank are absolutely right. However, in VS 2015 .. they added an easy way to detect a theme change. So you need to enable PlatformUI and you will get a super easy event

 using Microsoft.VisualStudio.PlatformUI; .... //Then you get an event VSColorTheme.ThemeChanged += VSColorTheme_ThemeChanged; 

You must make sure that your control is one-time, so you can unsubscribe from an event ...

BONUS!

It also gives you easy access to colors .. even if the user has changed them by default .. so that you can do things like this when you set your colors

 var defaultBackground = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowBackgroundColorKey); var defaultForeground = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowTextColorKey); 
+7
source

All Articles