简体   繁体   English

C# Visual Studio Excel 加载项:如何检测 Excel Office 主题更改?

[英]C# Visual Studio Excel Add-in: How can I detect Excel Office Theme Change?

I wrote a class that detects what is the current Excel theme.我写了一个 class 来检测当前的 Excel 主题是什么。

Get Excel current office theme:获取 Excel 当前办公主题:

//Declaration
string officeVersion;
int themeCode;

// Get Office Version first
officeVersion = "16.0";

// Goto the Registry Current Version
RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\" + officeVersion + @"\Common");

// Get Stored Theme
themeCode = (int)rk.GetValue("UI Theme", GlobalVar.COLORFUL);

Then based on the value of themeCode , I can determine what the current Excel theme is:然后根据themeCode的值,我可以确定当前的 Excel 主题是什么:

// Theme Constants
public const int COLORFUL = 0;
public const int DARKGREY = 3;
public const int BLACK = 4;
public const int WHITE = 5;

My question:我的问题:

  • How can I detect when the user, during Excel Running, change the Office Theme from the Excel Options ?如何检测用户何时在 Excel 运行期间从Excel 选项更改 Office 主题?
  • In Another way, is there any Excel Event triggered when the User has edited anything from the Excel Options?换句话说,当用户从 Excel 选项中编辑任何内容时,是否会触发任何 Excel 事件?
  • How can I detect/trap that event please?请问如何检测/捕获该事件?

在此处输入图像描述

I used already Process Monitor and got the location of the Registry key where the theme is stored.我已经使用了Process Monitor并获得了存储主题的注册表项的位置。 But I cannot constantly check the Registry, I prefer to detect when the user clicked on More Commmand\Excel Options if that event is detectable.但是我不能经常检查注册表,如果该事件是可检测的,我更愿意检测用户何时单击更多 Commmand\Excel 选项

Your answer and suggestions are most welcome.非常欢迎您的回答和建议。 Thanks in advance!提前致谢!

Great thanks to @PortlandRunner for the approach he gave me in the comments.非常感谢@PortlandRunner 在评论中给我的方法。 I came up with the following code:我想出了以下代码:

using Microsoft.Win32;
using System;
using System.Drawing;
using System.Management;
using System.Security.Principal;

namespace YourProject
{
    /*
     #####################################
     # GLOBAL CONSTANTS FOR OFFICE THEME #
     # By Tsiriniaina Rakotonirina       #
     #####################################
     */
    public class GlobalVar
    {
        //Theme Constants
        public const int COLORFUL = 0;
        public const int DARKGREY = 3;
        public const int BLACK = 4;
        public const int WHITE = 5;
    }

    /*
     ########################################
     # OFFICE CLASS TO RETURN TO THE ADDINS #
     # By Tsiriniaina Rakotonirina          #
     ########################################
     */
    public class ExcelTheme
    {
        private int code;             //Theme Code               
        private Color backgroundColor;//Addins Backcolor based on Theme
        private Color textForeColor;  //Addins Text Color based on Theme

        public Color BackgroundColor { get => backgroundColor; set => backgroundColor = value; }
        public Color TextForeColor { get => textForeColor; set => textForeColor = value; }
        public int Code { get => code; set => code = value; }
    }

    /*
     ###############################
     # OFFICE THEME CHANGE WATCHER #
     # By Tsiriniaina Rakotonirina #
     ###############################
     */
    class ExcelThemeWatcher
    {
        /*
         *****************************************
         * CLASS CONSTRUCTOR                     *
         * ---> The Watch start right away after *
         *      the class is created             *
         *****************************************
         */
        public ExcelThemeWatcher()
        {
            //Start Watching Office Theme Change
            //By calling the following method
            StartThemeWatcher();
        }

        /*
         *****************************************
         * GET OFFICE VERSION                    *
         * ---> Read the Registry and            *
         *      get the Current Office Version   *
         *****************************************
         */
        public int GetOfficeVersion()
        {
            //Get Current Excel Version
            try
            {
                //Get Office Version
                //Goto the Registry Current Version
                RegistryKey rk = Registry.ClassesRoot.OpenSubKey(@"Excel.Application\\CurVer");

                //Read Current Version
                string officeVersion = rk.GetValue("").ToString();

                //Office Version
                string officeNumberVersion = officeVersion.Split('.')[officeVersion.Split('.').GetUpperBound(0)];

                //Return Office Version
                return Int32.Parse(officeNumberVersion);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return 0;
            }
        }

        /*
         *****************************************
         * GET OFFICE THEME                      *
         * ---> Read the Registry and            *
         *      get the Current Office Theme     *
         *****************************************
         */
        private int GetRegistryOfficeTheme()
        {
            //Get Office Version first
            string officeVersion = GetOfficeVersion().ToString("F1");

            //Goto the Registry Current Version
            RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\" + officeVersion + @"\Common");

            return Convert.ToInt32(rk.GetValue("UI Theme", GlobalVar.COLORFUL));
        }

        /*
         *****************************************
         * GET ADDINS THEME                      *
         * ---> Based on the Office Theme        *
         *      Return the Addins Theme          *
         *****************************************
         */
        public ExcelTheme GetAddinsTheme()
        {
            ExcelTheme theme = new ExcelTheme();

            //Default Theme Code
            theme.Code = GetRegistryOfficeTheme();

            //Get Background Colors
            theme.BackgroundColor = ColorTranslator.FromHtml("#EFE9D7");
            theme.TextForeColor = ColorTranslator.FromHtml("#004B8D");

            try
            {
                switch (theme.Code)
                {
                    case GlobalVar.COLORFUL:
                        theme.BackgroundColor = ColorTranslator.FromHtml("#E6E6E6");
                        theme.TextForeColor = ColorTranslator.FromHtml("#004B8D");

                        break;

                    case GlobalVar.DARKGREY:
                        theme.BackgroundColor = ColorTranslator.FromHtml("#666666");
                        theme.TextForeColor = ColorTranslator.FromHtml("White");
                        break;

                    case GlobalVar.BLACK:
                        theme.BackgroundColor = ColorTranslator.FromHtml("#323130");
                        theme.TextForeColor = ColorTranslator.FromHtml("#CCA03B");
                        break;

                    case GlobalVar.WHITE:
                        theme.BackgroundColor = ColorTranslator.FromHtml("#FFFFFF");
                        theme.TextForeColor = ColorTranslator.FromHtml("#004B8D");

                        break;

                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return theme;
        }

        /*
         ******************************************
         * START OFFICE THEME CHANGE WATCH        *
         * ---> Using WMI, read and watch         *
         *      Registry Section for Office Theme *
         ******************************************
         */
        private void StartThemeWatcher()
        {
            string keyPath;   //Office Theme Path
            string valueName; //Office Theme Value name

            //Get Office Version first
            string officeVersion = GetOfficeVersion().ToString("F1");

            //Set the KeyPath based on the Office Version
            keyPath = @"Software\\Microsoft\\Office\\" + officeVersion + "\\Common";
            valueName = "UI Theme";

            //Get the Current User ID
            //---> HKEY_CURRENT_USER doesn't contain Value as it is a shortcut of HKEY_USERS + User ID
            //     That is why we get that currentUser ID and use it to read the wanted location

            //Get the User ID
            var currentUser = WindowsIdentity.GetCurrent();

            //Build the Query based on 3 parameters
            //Param #1: User ID
            //Param #2: Location or Path of the Registry Key
            //Param #3: Registry Value to watch
            var query = new WqlEventQuery(string.Format(
                    "SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND KeyPath='{0}\\\\{1}' AND ValueName='{2}'",
                    currentUser.User.Value, keyPath.Replace("\\", "\\\\"), valueName));

            //Create a Watcher based on the "query" we just built
            ManagementEventWatcher watcher = new ManagementEventWatcher(query);

            //Create the Event using the "Function" to fire up, here called "KeyValueChanged"
            watcher.EventArrived += (sender, args) => KeyValueChanged();

            //Start the Watcher
            watcher.Start();

        }

        /*
         ******************************************
         * EVENT FIRED UP WHEN CHANGE OCCURS      *
         * ---> Here the event is instructed      *
         *      to update the Addins Theme        *
         ******************************************
         */
        private void KeyValueChanged()
        {
            // Here, whenever the user change the Office theme,
            // this function will automatically Update the Addins Theme
            Globals.ThisAddIn.SetAddinsInterfaceTheme();
        }
    }

}

I didn't feel the need to stop the watcher , but if you came up with the idea, tell me where to put it;)我觉得没有必要阻止观察者,但如果你想出了这个主意,请告诉我把它放在哪里;)

UPDATE:更新:

It's good to tell as well that I was so existed when I tested to change the Office Theme and saw my Addins theme change as well.很高兴告诉我,当我测试更改 Office 主题并看到我的插件主题也发生了变化时,我是如此存在。 Would love to hear from you as well!也希望收到您的来信!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用于Office的C#Visual Studio工具会出现此错误:Excel遇到X加载项的问题 - C# Visual studio tools for office gives this error: Excel is running into problems with the X add-in MS Office Visual Studio加载项,共享加载项和Excel 2010加载项有什么区别? - What's the difference between an MS Office Visual Studio Add-in, Shared Add-in, and Excel 2010 Add-in? C#Visual Studio加载项-在保存文档时检测 - C# Visual Studio add-in - detect when saving document 我已经使用Visual Studio Express C#为2010 Office(64位)编写了Excel代码,如何在2010 Office(32位)上运行它? - I have written excel code for 2010 Office (64 bit) with visual studio express c#, how to run it on 2010 office (32 bit)? VSTO Excel加载项C#的安装文件(Visual Studio Professional 2017) - Setup File For VSTO Excel Add-In C# (Visual Studio Professional 2017) 如何获取当前Active Solution Platform名称以在Visual Studio加载项中使用? (C#) - How can I get the current Active Solution Platform name for use in a Visual Studio add-in? (C#) 如何使用C#中安装的Excel外接程序创建Excel电子表格? - How to create an excel spreadsheet with an excel add-in installed in c#? 使用Visual Studio Express的VSTO Excel加载项 - VSTO Excel Add-In with Visual Studio Express Visual Studio的C#interpreter加载项 - C# interpreter add-in for visual studio Excel COM加载项DLL-我可以直接从C#使用吗? - Excel COM add-in DLL's - Can I use directly from C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM