[英]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;)我觉得没有必要阻止观察者,但如果你想出了这个主意,请告诉我把它放在哪里;)
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.