Как я могу получить цвет акцента по умолчанию в Windows 10? - PullRequest
1 голос
/ 15 марта 2020

У меня есть приложение, и я хочу сделать его цвет фона по умолчанию Windows 10 Accent цвет, а когда пользователь меняет Windows 10's Accent цвет, я хочу, чтобы фон моего приложения цвет также меняется.

enter image description here

Ответы [ 3 ]

1 голос
/ 15 марта 2020

Вы можете переопределить WndProc для обработки сообщения WM_SETTINGCHANGE.
Когда это сообщение получено, вы можете определить, связано ли изменение настроек с изменением рабочего стола, проверяя сообщение * 1006. *: если это 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
} 
1 голос
/ 15 марта 2020

Вам нужно будет позвонить на UISettings.GetColorValue(UIColorType.Background), как задокументировано здесь .

0 голосов
/ 16 марта 2020

WinForms - это старая технология, которая не была сильно обновлена ​​для поддержки новых функций ОС. Нет хорошего способа получить цвет Accent с использованием базовых библиотек. Net (хотя существует взлом на основе реестра, использующий недокументированные ключи для получения значения). К счастью, вы можете получить доступ к некоторым Windows API времени выполнения, добавив пакет NUGET Microsoft. Windows .SDK.Contracts .

После добавления этого пакета вы можете создать экземпляр класса Windows .UI.ViewManagement.UISettings , а затем использовать метод UISettings.GetColorValue (UIColorType) для получения значения.

Чтобы получать уведомления об изменениях значения, вы можете подписаться на SystemEvents.UserPreferenceChanged Event . Это событие классифицирует изменение как изменение типа UserPreferenceCategory.General , которое используется по умолчанию, когда старый лог c не знает, что изменилось (снова старый код не обновляется для новых функций). Вы можете обнаружить изменения с помощью listenimg для сообщения WM_SETTINGCHANGE и проверить, когда WParam имеет значение NULL, а 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...