なぜこの記事を書こうと思ったのか
Windows11で毎回 デスクトップ → 右クリック → 個人用設定 → 色 → モードを選ぶ → ダークとライトを切り替え が面倒だったのでRustで色を切り替える処理を作ってみました。
CSSで、ライトモードとダークモードの色を調整する場合には便利かもしれません。
出来あがったもの
コード
Cargo.toml
[package]
name = "toggle_os_theme"
version = "0.1.0"
edition = "2024"
[dependencies]
winreg = "0.52"
windows = { version = "0.52", features = [
"Win32_UI_WindowsAndMessaging",
"Win32_Foundation"
] }
main.rs
#![windows_subsystem = "windows"]
use winreg::enums::*;
use winreg::RegKey;
use windows::Win32::UI::WindowsAndMessaging::{
SendMessageTimeoutW, SMTO_ABORTIFHUNG, WM_SETTINGCHANGE,
};
use windows::Win32::Foundation::HWND;
fn is_dark_mode() -> Result<bool, Box<dyn std::error::Error>> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let personalize = hkcu.open_subkey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
)?;
let apps_use_light: u32 = personalize.get_value("AppsUseLightTheme")?;
Ok(apps_use_light == 0)// 0 = dark, 1 = light
}
fn set_dark_mode(dark: bool) -> Result<(), Box<dyn std::error::Error>> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let personalize = hkcu.open_subkey_with_flags(
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
KEY_WRITE,
)?;
let value = if dark { 0u32 } else { 1u32 };
personalize.set_value("AppsUseLightTheme", &value)?;
personalize.set_value("SystemUsesLightTheme", &value)?;
unsafe {
SendMessageTimeoutW(
HWND(0xffff), // HWND_BROADCAST
WM_SETTINGCHANGE,
None,
None,
SMTO_ABORTIFHUNG,
100,
None,
);
}
Ok(())
}
fn toggle_os_theme(){
let is_dark_result = is_dark_mode();
let Ok(mut is_dark) = is_dark_result else {return };
is_dark = !is_dark;
set_dark_mode(is_dark).unwrap();
}
fn main() {
toggle_os_theme();
}
