Skip to content

Commit 171a0ce

Browse files
committed
fix(win): transparent label
1 parent 4dad117 commit 171a0ce

4 files changed

Lines changed: 64 additions & 35 deletions

File tree

src/runtime/windows.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ use windows_sys::{
1919
Foundation::{COLORREF, HANDLE, HWND, LPARAM, LRESULT, POINT, RECT, WAIT_FAILED, WPARAM},
2020
Graphics::Gdi::{
2121
BLACK_BRUSH, CreateSolidBrush, GetStockObject, HDC, InvalidateRect, Rectangle,
22-
ScreenToClient, SelectObject, SetBkColor, SetBkMode, SetTextColor, TRANSPARENT,
23-
WHITE_BRUSH,
22+
ScreenToClient, SelectObject, SetBkColor, SetTextColor, WHITE_BRUSH,
2423
},
2524
System::Threading::INFINITE,
2625
UI::{
@@ -42,7 +41,8 @@ use windows_sys::{
4241
use super::RUNTIME;
4342
use crate::ui::{
4443
darkmode::{
45-
children_refresh_dark_mode, init_dark, is_dark_mode_allowed_for_app, window_use_dark_mode,
44+
children_refresh_dark_mode, control_color_static, init_dark, is_dark_mode_allowed_for_app,
45+
window_use_dark_mode,
4646
},
4747
dpi::get_dpi_for_window,
4848
font::{WinBrush, default_font},
@@ -296,18 +296,7 @@ pub(crate) unsafe extern "system" fn window_proc(
296296
InvalidateRect(handle, null(), 1);
297297
}
298298
WM_CTLCOLORSTATIC => {
299-
let dark = is_dark_mode_allowed_for_app();
300-
let hdc = wparam as HDC;
301-
SetBkMode(hdc, TRANSPARENT as _);
302-
if dark {
303-
SetTextColor(hdc, WHITE);
304-
SetBkColor(hdc, BLACK);
305-
}
306-
return if dark {
307-
GetStockObject(BLACK_BRUSH)
308-
} else {
309-
GetStockObject(WHITE_BRUSH)
310-
} as _;
299+
return control_color_static(lparam as HWND, wparam as HDC);
311300
}
312301
WM_CTLCOLORBTN => {
313302
if is_dark_mode_allowed_for_app() {

src/ui/windows/darkmode/hook.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use widestring::U16CStr;
1010
use windows_sys::{
1111
Win32::{
1212
Foundation::{COLORREF, HWND, LPARAM, LRESULT, RECT, S_OK, WPARAM},
13-
Globalization::{CSTR_EQUAL, CompareStringW, LOCALE_ALL, NORM_IGNORECASE},
1413
Graphics::{
1514
Dwm::DwmSetWindowAttribute,
1615
Gdi::{
@@ -40,7 +39,10 @@ use windows_sys::{
4039
w,
4140
};
4241

43-
use crate::ui::{darkmode::PreferredAppMode, font::WinBrush};
42+
use crate::ui::{
43+
darkmode::{PreferredAppMode, WHITE, u16_string_eq_ignore_case},
44+
font::WinBrush,
45+
};
4446

4547
#[link(name = "ntdll")]
4648
extern "system" {
@@ -240,8 +242,6 @@ unsafe extern "system" fn dark_draw_theme_text(
240242
dwtextflags2: u32,
241243
prect: *const RECT,
242244
) -> HRESULT {
243-
const WHITE: COLORREF = 0x00FFFFFF;
244-
245245
if is_dark_mode_allowed_for_app()
246246
&& (ipartid == BP_CHECKBOX || ipartid == BP_RADIOBUTTON)
247247
&& istateid != PBS_DISABLED
@@ -370,20 +370,6 @@ pub unsafe fn children_refresh_dark_mode(handle: HWND, lparam: LPARAM) {
370370
EnumChildWindows(handle, Some(enum_callback), lparam);
371371
}
372372

373-
#[inline]
374-
fn u16_string_eq_ignore_case(s1: &U16CStr, s2: *const u16) -> bool {
375-
unsafe {
376-
CompareStringW(
377-
LOCALE_ALL,
378-
NORM_IGNORECASE,
379-
s1.as_ptr(),
380-
s1.len() as _,
381-
s2,
382-
-1,
383-
) == CSTR_EQUAL
384-
}
385-
}
386-
387373
pub unsafe fn control_use_dark_mode(hwnd: HWND, misc_task_dialog: bool) {
388374
let mut class = [0u16; MAX_CLASS_NAME as usize];
389375
GetClassNameW(hwnd, class.as_mut_ptr(), MAX_CLASS_NAME);

src/ui/windows/darkmode/mod.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
use widestring::U16CStr;
2+
use windows_sys::Win32::{
3+
Foundation::{COLORREF, HWND, LRESULT},
4+
Globalization::{CSTR_EQUAL, CompareStringW, LOCALE_ALL, NORM_IGNORECASE},
5+
Graphics::Gdi::{
6+
BLACK_BRUSH, GetStockObject, HDC, NULL_BRUSH, SetBkColor, SetBkMode, SetTextColor,
7+
TRANSPARENT, WHITE_BRUSH,
8+
},
9+
System::SystemServices::MAX_CLASS_NAME,
10+
UI::{Controls::WC_STATICW, WindowsAndMessaging::GetClassNameW},
11+
};
12+
113
cfg_if::cfg_if! {
214
if #[cfg(feature = "windows-dark-mode")] {
315
#[path = "hook.rs"]
@@ -19,3 +31,45 @@ pub enum PreferredAppMode {
1931
ForceDark = 2,
2032
ForceLight = 3,
2133
}
34+
35+
#[inline]
36+
fn u16_string_eq_ignore_case(s1: &U16CStr, s2: *const u16) -> bool {
37+
unsafe {
38+
CompareStringW(
39+
LOCALE_ALL,
40+
NORM_IGNORECASE,
41+
s1.as_ptr(),
42+
s1.len() as _,
43+
s2,
44+
-1,
45+
) == CSTR_EQUAL
46+
}
47+
}
48+
49+
const WHITE: COLORREF = 0x00FFFFFF;
50+
const BLACK: COLORREF = 0x00000000;
51+
52+
pub unsafe fn control_color_static(hwnd: HWND, hdc: HDC) -> LRESULT {
53+
let dark = is_dark_mode_allowed_for_app();
54+
55+
let mut class = [0u16; MAX_CLASS_NAME as usize];
56+
GetClassNameW(hwnd, class.as_mut_ptr(), MAX_CLASS_NAME);
57+
let class = U16CStr::from_ptr_str(class.as_ptr());
58+
let is_static = u16_string_eq_ignore_case(class, WC_STATICW);
59+
60+
SetBkMode(hdc, TRANSPARENT as _);
61+
if dark {
62+
SetTextColor(hdc, WHITE);
63+
if !is_static {
64+
SetBkColor(hdc, BLACK);
65+
}
66+
}
67+
let res = if is_static {
68+
GetStockObject(NULL_BRUSH)
69+
} else if dark {
70+
GetStockObject(BLACK_BRUSH)
71+
} else {
72+
GetStockObject(WHITE_BRUSH)
73+
};
74+
res as _
75+
}

src/ui/windows/label.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use windows_sys::Win32::{
55
System::SystemServices::{SS_CENTER, SS_LEFT, SS_RIGHT},
66
UI::{
77
Controls::WC_STATICW,
8-
WindowsAndMessaging::{WS_CHILD, WS_VISIBLE},
8+
WindowsAndMessaging::{WS_CHILD, WS_EX_TRANSPARENT, WS_VISIBLE},
99
},
1010
};
1111

@@ -24,7 +24,7 @@ impl Label {
2424
let mut handle = Widget::new(
2525
WC_STATICW,
2626
WS_CHILD | WS_VISIBLE | SS_LEFT,
27-
0,
27+
WS_EX_TRANSPARENT,
2828
parent.as_window().as_raw_window(),
2929
);
3030
handle.set_size(handle.size_d2l((100, 50)));

0 commit comments

Comments
 (0)