Rust 쓰지 않으니 늘지 않는군요…
[Cargo.toml]
[package]
name = "dark_window"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies.windows]
version = "0.43.0"
features = [
"Win32_Foundation",
"Win32_System_Registry",
"Win32_Graphics_Gdi",
"Win32_Graphics_Dwm",
"Win32_System_LibraryLoader",
"Win32_UI_WindowsAndMessaging",
]
[dependencies]
[main.rs]
#![windows_subsystem = "windows"]
use windows::{
core::*, Win32::Foundation::*, Win32::System::Registry::*,
Win32::Graphics::Dwm::*, Win32::Graphics::Gdi::*,
Win32::System::LibraryLoader::GetModuleHandleA, Win32::UI::WindowsAndMessaging::*,
};
#[allow(dead_code)]
static mut IS_DARK_MODE: bool = false;
fn check_dark_mode(hwnd: HWND) {
unsafe {
let mut key = HKEY::default();
RegOpenKeyExA(HKEY_CURRENT_USER, s!("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"), 0, KEY_READ, &mut key);
let mut len = std::mem::size_of::<u32>() as u32;
let mut buffer = vec![0u8; len as usize];
RegQueryValueExA(key, s!("AppsUseLightTheme"), None, None, Some(buffer.as_mut_ptr() as _), Some(&mut len));
RegCloseKey(key);
if buffer[0] == 0 {
IS_DARK_MODE = true
} else {
IS_DARK_MODE = false
}
let value:u32 = IS_DARK_MODE as u32;
DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value as *const u32 as *const _, std::mem::size_of::<u32>() as u32).unwrap();
}
}
fn main() -> Result<()> {
unsafe {
let instance = GetModuleHandleA(None)?;
debug_assert!(instance.0 != 0);
let window_class = s!("window");
let wc = WNDCLASSA {
hCursor: LoadCursorW(None, IDC_ARROW)?,
hInstance: instance,
lpszClassName: window_class,
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some(wndproc),
..Default::default()
};
let atom = RegisterClassA(&wc);
debug_assert!(atom != 0);
let cx = 320;
let cy = 240 + GetSystemMetrics(SM_CYCAPTION);
let cx_scrn = GetSystemMetrics(SM_CXFULLSCREEN);
let cy_scrn = GetSystemMetrics(SM_CYFULLSCREEN);
let x = (cx_scrn - cx) / 2;
let y = (cy_scrn - cy) / 2;
let hwnd = CreateWindowExA(
WINDOW_EX_STYLE::default(),
window_class,
s!("Dark Window"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
x,
y,
cx,
cy,
None,
None,
instance,
None,
);
check_dark_mode(hwnd);
let mut message = MSG::default();
while GetMessageA(&mut message, None, 0, 0).into() {
DispatchMessageA(&message);
}
Ok(())
}
}
extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
unsafe {
match message {
WM_PAINT => {
let mut ps = PAINTSTRUCT::default();
let hdc = BeginPaint(window, &mut ps);
let brush = match IS_DARK_MODE {
false => CreateSolidBrush(COLORREF(0x00ffffff)),
true => CreateSolidBrush(COLORREF(0)),
};
FillRect(hdc, &ps.rcPaint as *const RECT, brush);
DeleteObject(brush);
EndPaint(window, &ps);
LRESULT(0)
}
WM_DESTROY => {
println!("WM_DESTROY");
PostQuitMessage(0);
LRESULT(0)
}
WM_SETTINGCHANGE => {
println!("WM_SETTINGCHANGE");
check_dark_mode(window);
InvalidateRect(window, None, true);
LRESULT(0)
}
_ => DefWindowProcA(window, message, wparam, lparam),
}
}
}
microsoft/windows-rs: Rust for Windows (github.com)
Support Dark and Light themes in Win32 apps - Windows apps | Microsoft Learn