【问题标题】:How can i get the default accent color in Windows 10?如何在 Windows 10 中获得默认的强调色?
【发布时间】:2020-03-15 15:43:19
【问题描述】:

我有一个应用程序,我想将其背景颜色设为默认的 Windows 10 Accent 颜色,当用户更改 Windows 10 的 Accent 颜色时,我也希望我的应用程序的背景颜色变化。

【问题讨论】:

  • 从您的图形中,您看起来像是从“颜色”设置页面中选择了 Accent 颜色,而不是从“背景设置”页面中选择了背景颜色。获取背景颜色很容易,而获取强调色则更复杂。
  • 是的,我需要强调色

标签: c# windows winforms


【解决方案1】:

您需要致电UISettings.GetColorValue(UIColorType.Background),如记录的here

【讨论】:

  • 啊,但是只是给这个值设置一个颜色不会让它在用户更改Windows 10背景颜色时更新,所以这个答案不完整
【解决方案2】:

WinForms 是一项旧技术,尚未进行太多更新以支持新的操作系统功能。没有使用基本 .Net 库获取 Accent 颜色的好方法(尽管有一个基于注册表的黑客使用未记录的键来检索值)。幸运的是,您可以通过添加 NUGET 包 Microsoft.Windows.SDK.Contracts 来访问某些 Windows 运行时 API。

添加此包后,您可以创建Windows.UI.ViewManagement.UISettings Class 的实例,然后使用UISettings.GetColorValue(UIColorType) Method 检索值。

要收到值更改的通知,您可以订阅SystemEvents.UserPreferenceChanged Event。此事件将更改归类为 UserPreferenceCategory.General 类型更改,这是旧逻辑不知道发生了什么更改时的默认值(同样旧代码未针对新功能更新)。您可以通过listenimg 检测WM_SETTINGCHANGE message 的更改并检查WParam 何时为空并且LParam 指向一个字符串(“ImmersiveColorSet”),但这依赖于字符串值永远不会改变并且并不比对所有响应好多少UserPreferenceCategory.General 更改。

综上所述,一个简单的实现如下:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        UserPreferenceChangedEventHandler UserPerferenceChanged = (s, e) =>
        { if (e.Category == UserPreferenceCategory.General || e.Category == UserPreferenceCategory.VisualStyle) BackColor = GetAccentColor(); };

        SystemEvents.UserPreferenceChanged += UserPerferenceChanged;
        Disposed += (object s, EventArgs e) => { SystemEvents.UserPreferenceChanged -= UserPerferenceChanged; };
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        BackColor = GetAccentColor();
    }

    static Windows.UI.ViewManagement.UISettings uiSettings = new Windows.UI.ViewManagement.UISettings();
    private static System.Drawing.Color GetAccentColor()
    {
        Windows.UI.Color c = uiSettings.GetColorValue(Windows.UI.ViewManagement.UIColorType.Accent);
        return Color.FromArgb(c.A, c.R, c.G, c.B);
    }
}

【讨论】:

  • 你说 WinForm 是老技术,这是什么意思?我是编程新手,我想创建 Windwos 应用程序。你能告诉我关于创建窗口应用程序的新技术吗?
  • @MahmoodGaribov - 我可能应该称它为一种成熟的 UI 技术,它封装了更旧的 Win32 API,并且几乎没有更新。几年前它才开始获得高 DPI 支持,即使这样也有一定的局限性。也就是说,对于不需要花哨的图形界面的简单项目来说,它仍然是一个可行的平台。您可以为其添加功能,但这需要自定义编码(即不要期望仅仅因为您想要它而添加功能)。基于 XAML 的 GUI(例如 WPF 和 UWP)被认为是桌面应用程序的推荐路径。
【解决方案3】:

您可以覆盖WndProc 来处理WM_SETTINGCHANGE 消息。
收到此消息后,您可以通过检查消息WParam 来确定设置更改是否与桌面更改有关:如果是SPI_SETDESKWALLPAPER,则桌面设置已更改。

背景颜色的变化是这样通知的。
当您收到消息时,颜色值已更改,因此您可以使用 SystemColors 类检索它:SystemColors.Desktop 返回桌面的当前颜色。

private const int WM_SETTINGCHANGE = 0x001A;
private const int SPI_SETDESKWALLPAPER = 0x0014;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg) {
        case WM_SETTINGCHANGE:
            if (m.WParam.ToInt32() == SPI_SETDESKWALLPAPER) {
                this.BackColor = SystemColors.Desktop;
            }
            m.Result = IntPtr.Zero;
            break;
        // other case switches
} 

【讨论】:

    猜你喜欢
    • 2020-01-14
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 2011-06-01
    • 2015-03-17
    • 2016-05-27
    相关资源
    最近更新 更多