I am currently adding support for the Dark / Light themes of Visual Studio 2012 in my MZ-Tools 7.0 add-in for Visual Studio, which is resulting much harder than expected because there are a lot of issues. I will blog about them in a future post when the work is done, but meantime I have written this sample to show how an add-in can know the current theme and how to get notified when the theme is changed:
HOWTO: Get the current theme and detect changing it from a Visual Studio 2012 add-in.
One thing that may surprise you is that if you have opened several VS 2012 instances, changing the theme in one of them changes it in ALL of them. So, it is not enough for an add-in to know when the theme has been changed through the Tools, Options window of the instance where it is hosted. Visual Studio 2012 broadcasts a
WM_SYSCOLORCHANGE message, so an add-in must intercept that message through some top-level window. While an add-in could do subclassing of the main IDE window, that’s an approach prone to crashes if two extensions do the same (because subclassing must be undone in reverse order), so my sample uses a dummy invisible top-level form.
The new Visual Studio 2012 IDE and SDK introduces new services and methods related to themes, for example the IVsShell5 interface of the Microsoft.VisualStudio.Shell.Interop.11.0.dll assembly, so maybe there is some other way to get notified when the theme changes (I don’t know), but my approach with MZ-Tools is to use a single binary add-in dll, so I can’t add as references assemblies that are not in VS 2005, as I explained in the article:
HOWTO: Create an add-in that targets several Visual Studio versions with the same add-in DLL using C# or VB.NET.
2 thoughts on “MZ-Tools Articles Series: HOWTO: Get the current theme and detect changing it from a Visual Studio 2012 add-in.”
The package-based approach is: on a VS IServiceProvider, QueryService for IVsShell. IVsBroadcastMessageEvents is an interface you implement that gets passed to IVsShell::AdviseBroadcastMessages. In your IVsBroadcastMessageEvents::OnBroadcastMessage implementation, listen for WM_SYSCOLORCHANGE.
Thanks for the info, Sean
Comments are closed.