80 lines
1.8 KiB
Rust
80 lines
1.8 KiB
Rust
use clap::Parser;
|
|
use winsafe::{
|
|
co::{PROCESS, PROCESS_NAME, SWP},
|
|
prelude::*,
|
|
EnumWindows, HwndPlace, HPROCESS, HWND, POINT,
|
|
};
|
|
|
|
mod model;
|
|
use model::*;
|
|
|
|
fn filter_target_windows(hwnd: &HWND, q: &TargetInformation) -> bool {
|
|
if !q.title_contains.is_empty() {
|
|
let Ok(title) = hwnd.GetWindowText() else {
|
|
return false;
|
|
};
|
|
|
|
if q.title_contains
|
|
.iter()
|
|
.all(|s| !title.to_ascii_lowercase().contains(&s.to_ascii_lowercase()))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if !q.path_endswith.is_empty() {
|
|
let (_, pid) = hwnd.GetWindowThreadProcessId();
|
|
|
|
let Ok(proc) = HPROCESS::OpenProcess(PROCESS::QUERY_LIMITED_INFORMATION, false, pid) else {
|
|
return false;
|
|
};
|
|
|
|
let Ok(path) = proc.QueryFullProcessImageName(PROCESS_NAME::WIN32) else {
|
|
return false;
|
|
};
|
|
|
|
if q.path_endswith
|
|
.iter()
|
|
.all(|s| !path.to_ascii_lowercase().ends_with(&s.to_ascii_lowercase()))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
true
|
|
}
|
|
|
|
fn window_callback(hwnd: HWND, op: &Cli) {
|
|
if !filter_target_windows(&hwnd, &op.target) {
|
|
return;
|
|
}
|
|
|
|
let client_size = Size::from(hwnd.GetClientRect().unwrap());
|
|
|
|
let Some(size) = op.size else {
|
|
println!("{}\t", client_size - op.target.offset);
|
|
return;
|
|
};
|
|
|
|
let window_size = Size::from(hwnd.GetWindowRect().unwrap());
|
|
|
|
let border = window_size - client_size;
|
|
|
|
hwnd.SetWindowPos(
|
|
HwndPlace::None,
|
|
POINT::new(0, 0),
|
|
(size + op.target.offset + border).into(),
|
|
SWP::NOMOVE,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
let c = Cli::parse();
|
|
EnumWindows(|hwnd: HWND| -> bool {
|
|
window_callback(hwnd, &c);
|
|
true
|
|
})
|
|
.unwrap();
|
|
}
|