#![allow(unsafe_op_in_unsafe_fn)]
use crate::types::*;
use super::base::Component;
use crate::w;
unsafe extern "system" fn progress_subclass_proc(hwnd: HWND, msg: u32, wparam: usize, lparam: isize) -> isize {
match msg {
WM_NCPAINT => {
return 0;
},
WM_NCCALCSIZE => {
if wparam != 0 {
return 0;
}
},
WM_DESTROY => {
let old_proc_ptr = GetPropW(hwnd, crate::w!("CompactRs_OldProc").as_ptr());
if old_proc_ptr != std::ptr::null_mut() {
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, old_proc_ptr as isize);
RemovePropW(hwnd, crate::w!("CompactRs_OldProc").as_ptr());
}
},
_ => {}
}
let old_proc_ptr = GetPropW(hwnd, crate::w!("CompactRs_OldProc").as_ptr());
if old_proc_ptr != std::ptr::null_mut() {
let old_proc: unsafe extern "system" fn(HWND, u32, usize, isize) -> isize = std::mem::transmute(old_proc_ptr);
return CallWindowProcW(Some(old_proc), hwnd, msg, wparam, lparam);
}
0
}
pub struct StatusBarIds {
pub label_id: u16,
pub progress_id: u16,
}
pub struct StatusBar {
hwnd_label: HWND,
hwnd_progress: HWND,
label_id: u16,
progress_id: u16,
x: i32,
y: i32,
width: i32,
}
impl StatusBar {
pub fn new(ids: StatusBarIds) -> Self {
Self {
hwnd_label: std::ptr::null_mut(),
hwnd_progress: std::ptr::null_mut(),
label_id: ids.label_id,
progress_id: ids.progress_id,
x: 0,
y: 0,
width: 0,
}
}
#[inline]
pub fn label_hwnd(&self) -> HWND {
self.hwnd_label
}
#[inline]
pub fn progress_hwnd(&self) -> HWND {
self.hwnd_progress
}
pub unsafe fn set_font(&self, hfont: HFONT) {
let wparam = hfont as usize;
let lparam = 1;
SendMessageW(self.hwnd_label, WM_SETFONT, wparam, lparam);
}
}
impl Component for StatusBar {
unsafe fn create(&mut self, parent: HWND) -> Result<(), String> {
unsafe {
let instance = GetModuleHandleW(std::ptr::null_mut());
let label_text = w!("Drag and drop files or folders, or use 'Files'/'Folder' buttons. Then click 'Process All'.");
let static_cls = w!("STATIC");
self.hwnd_label = CreateWindowExW(
0,
static_cls.as_ptr(),
label_text.as_ptr(),
WS_CHILD | WS_VISIBLE,
10,
10,
860,
25,
parent,
self.label_id as usize as HMENU,
instance,
std::ptr::null_mut(),
);
if self.hwnd_label == std::ptr::null_mut() {
return Err("Failed to create status label".to_string());
}
let empty_text = w!("");
self.hwnd_progress = CreateWindowExW(
0,
PROGRESS_CLASSW,
empty_text.as_ptr(),
WS_VISIBLE | WS_CHILD | PBS_SMOOTH,
10,
430,
860,
20,
parent,
self.progress_id as usize as HMENU,
instance,
std::ptr::null_mut(),
);
if self.hwnd_progress == std::ptr::null_mut() {
return Err("Failed to create progress bar".to_string());
}
let old_proc = SetWindowLongPtrW(self.hwnd_progress, GWLP_WNDPROC, progress_subclass_proc as *const () as isize);
SetPropW(self.hwnd_progress, crate::w!("CompactRs_OldProc").as_ptr(), old_proc as isize as _);
let mut style = GetWindowLongW(self.hwnd_progress, GWL_STYLE) as u32;
style &= !(WS_BORDER | WS_DLGFRAME);
SetWindowLongW(self.hwnd_progress, GWL_STYLE, style as i32);
let mut ex_style = GetWindowLongW(self.hwnd_progress, GWL_EXSTYLE) as u32;
ex_style &= !(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
SetWindowLongW(self.hwnd_progress, GWL_EXSTYLE, ex_style as i32);
SetWindowPos(self.hwnd_progress, std::ptr::null_mut(), 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
Ok(())
}
}
fn hwnd(&self) -> Option<HWND> {
Some(self.hwnd_progress)
}
unsafe fn on_resize(&mut self, parent_rect: &RECT) {
unsafe {
let width = parent_rect.right - parent_rect.left;
let height = parent_rect.bottom - parent_rect.top;
let padding = 10;
let header_height = 25;
let progress_height = 20;
self.x = padding;
self.width = width - padding * 2;
let base_y = parent_rect.top;
let label_abs_y = padding;
SetWindowPos(
self.hwnd_label,
std::ptr::null_mut(),
padding,
label_abs_y,
width - padding - 220, header_height,
SWP_NOZORDER,
);
let progress_local_y = (height - progress_height) / 2;
self.y = base_y + progress_local_y;
SetWindowPos(
self.hwnd_progress,
std::ptr::null_mut(),
padding,
self.y,
width - padding * 2,
progress_height,
SWP_NOZORDER,
);
}
}
unsafe fn on_theme_change(&mut self, is_dark: bool) {
unsafe {
if self.hwnd_progress != std::ptr::null_mut() {
crate::ui::theme::apply_theme(self.hwnd_progress, crate::ui::theme::ControlType::ProgressBar, is_dark);
const PBM_SETBKCOLOR: u32 = 0x2001;
const PBM_SETBARCOLOR: u32 = 1033;
if is_dark {
SendMessageW(self.hwnd_progress, PBM_SETBKCOLOR, 0, crate::ui::theme::COLOR_DARK_BG as isize);
SendMessageW(self.hwnd_progress, PBM_SETBARCOLOR, 0, 0x0000D000); } else {
}
}
if self.hwnd_label != std::ptr::null_mut() {
crate::ui::theme::apply_theme(self.hwnd_label, crate::ui::theme::ControlType::Window, is_dark);
SendMessageW(self.hwnd_label, WM_SETFONT, crate::ui::theme::get_app_font() as usize, 1);
}
}
}
}