c-s*_*ile 20 windows winapi win32gui windows-10
一点上下文:Sciter(纯win32应用程序)已经能够呈现UWP相似的UI:
Windows 10.1803在Settings applet中引入了Dark/Light开关,例如,如此处所示.
问题:如何确定Win32应用程序中"app mode"的当前类型?
use*_*670 19
好吧,看起来这个选项没有直接暴露给常规的win32应用程序,但可以通过AppsUseLightTheme(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)AppsUseLightTheme注册表项设置/检索它.
要添加到@user7860670建议的解决方案,即:检查注册表项AppsUseLightTheme,我认为值得有一些代码示例。
Win32有RegGetValue从注册表中读取。
bool is_light_theme() {
    // based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
    // The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
    auto buffer = std::vector<char>(4);
    auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
    auto res = RegGetValueW(
        HKEY_CURRENT_USER,
        L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
        L"AppsUseLightTheme",
        RRF_RT_REG_DWORD, // expected value type
        nullptr,
        buffer.data(),
        &cbData);
    if (res != ERROR_SUCCESS) {
        throw std::runtime_error("Error: error_code=" + std::to_string(res));
    }
    // convert bytes written to our buffer to an int, assuming little-endian
    auto i = int(buffer[3] << 24 |
        buffer[2] << 16 |
        buffer[1] << 8 |
        buffer[0]);
    return i == 1;
}
使用windows-rs投影箱:
pub fn is_light_theme() -> bool {
    // based on https://stackoverflow.com/a/51336913/709884
    let mut buffer: [u8; 4] = [0; 4];
    let mut cb_data: u32 = (buffer.len()).try_into().unwrap();
    let res = unsafe {
        RegGetValueW(
            HKEY_CURRENT_USER,
            r#"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"#
                .to_wide()
                .as_pwstr(),
            "AppsUseLightTheme".to_wide().as_pwstr(),
            RRF_RT_REG_DWORD,
            std::ptr::null_mut(),
            buffer.as_mut_ptr() as _,
            &mut cb_data as *mut _,
        )
    };
    assert_eq!(
        res,
        ERROR_SUCCESS,
        format!("failed to read key from registry: err_code={}", res).as_str(),
    );
    // REG_DWORD is signed 32-bit, using little endian
    let light_mode = i32::from_le_bytes(buffer) == 1;
    light_mode
}
pub fn is_dark_theme() -> bool {
    !is_light_theme()
}
// convert &str to Win32 PWSTR
#[derive(Default)]
pub struct WideString(pub Vec<u16>);
pub trait ToWide {
    fn to_wide(&self) -> WideString;
}
impl ToWide for &str {
    fn to_wide(&self) -> WideString {
        let mut result: Vec<u16> = self.encode_utf16().collect();
        result.push(0);
        WideString(result)
    }
}
impl ToWide for String {
    fn to_wide(&self) -> WideString {
        let mut result: Vec<u16> = self.encode_utf16().collect();
        result.push(0);
        WideString(result)
    }
}
impl WideString {
    pub fn as_pwstr(&self) -> PWSTR {
        PWSTR(self.0.as_ptr() as *mut _)
    }
}
编辑:只要您在启用 c++17 的情况下构建,就说明这适用于所有 Win32 项目。
如果您使用的是最新的 SDK,这对我有用。
#include <winrt/Windows.UI.ViewManagement.h>
using namespace winrt::Windows::UI::ViewManagement;
if (RUNNING_ON_WINDOWS_10) {
  UISettings settings;
  auto background = settings.GetColorValue(UIColorType::Background);
  auto foreground = settings.GetColorValue(UIColorType::Foreground);
}
该Microsoft.Windows.SDK.ContractsNuGet包给人的.NET Framework 4.5+和.NET核心3.0+应用程序访问Windows 10的WinRT API,包括Windows.UI.ViewManagement.Settings中提到的答案jarjar。将此包添加到包含以下代码的 .NET Core 3.0 控制台应用程序:
using System;
using Windows.UI.ViewManagement;
namespace WhatColourAmI
{
    class Program
    {
        static void Main(string[] args)
        {
            var settings = new UISettings();
            var foreground = settings.GetColorValue(UIColorType.Foreground);
            var background = settings.GetColorValue(UIColorType.Background);
            Console.WriteLine($"Foreground {foreground} Background {background}");
        }
    }
}
主题设置为Dark时的输出为:
前景#FF FFFFFF背景#FF 000000
当主题设置为Light 时,它是:
前景#FF 000000背景#FF FFFFFF
由于这是通过 Microsoft 提供的软件包公开的,该软件包指出:
此软件包包括所有受支持的 Windows 运行时 API,最高可达 Windows 10 版本 1903
可以肯定的是,这个 API 是可访问的!
注意:这不是明确检查主题是浅色还是深色,而是检查表明使用的主题是两者之一的一对值,因此,.. 这种方法的正确性有点可疑,但它在至少是一种“纯粹的”C# 方式来实现在其他地方用 C++ 概述的内容
| 归档时间: | 
 | 
| 查看次数: | 3744 次 | 
| 最近记录: |