다크 윈도우

Rust 쓰지 않으니 늘지 않는군요…
전혀 성장하지 않았어

DarkWindow

[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

1개의 좋아요

최근에 마소에서 윈도우 커널 코드를 러스트로 조금씩 대체하고 있다던데 저도 러스트로 네이티브 프로그램 짜는거 연습해보고싶네요 ㅎ.ㅎ

3개의 좋아요