pub mod key_click;
pub mod key_down;
pub mod key_up;
pub use key_click::KeyClickHandler;
pub use key_down::KeyDownHandler;
pub use key_up::KeyUpHandler;
use crate::keyboard::keyboard_input;
use crate::script_engine::instruction::ScriptError;
use crate::utils::key_code;
#[derive(Clone)]
pub struct KeyClickParams {
pub key_down_input: windows::Win32::UI::Input::KeyboardAndMouse::INPUT,
pub key_up_input: windows::Win32::UI::Input::KeyboardAndMouse::INPUT,
pub delay_ms: u32,
}
#[derive(Clone)]
pub struct KeyDownParams {
pub input: windows::Win32::UI::Input::KeyboardAndMouse::INPUT,
}
#[derive(Clone)]
pub struct KeyUpParams {
pub input: windows::Win32::UI::Input::KeyboardAndMouse::INPUT,
}
#[derive(Clone)]
pub struct KeyPostClickParams {
pub vk_code: u8,
pub scan_code: u16,
pub delay_ms: u32,
}
#[derive(Clone)]
pub struct KeyPostDownUpParams {
pub vk_code: u8,
pub scan_code: u16,
}
#[derive(Clone)]
pub enum KeyParams {
SendClick(KeyClickParams),
SendDown(KeyDownParams),
SendUp(KeyUpParams),
PostClick(KeyPostClickParams),
PostDown(KeyPostDownUpParams),
PostUp(KeyPostDownUpParams),
}
pub fn parse_key_click_args(args: &[&str]) -> Result<KeyParams, ScriptError> {
if args.is_empty() {
return Err(ScriptError::ParseError(
"Missing key name. Usage: key <name> [delay_ms] [mode]".into(),
));
}
let vk = key_code(args[0]);
if vk == 0 {
return Err(ScriptError::ParseError(format!(
"Unknown key name: '{}'",
args[0]
)));
}
let scan_code = crate::get_scan_code(vk);
let extended = crate::utils::key_code::is_extended_key(vk as u8);
let mut delay_ms = 0u32;
let mut mode_send = true;
if args.len() > 1 {
match args[1].parse::<u32>() {
Ok(delay) => {
delay_ms = delay;
if args.len() > 2 {
mode_send = match args[2] {
"post" => false,
"send" => true,
other => {
return Err(ScriptError::ParseError(format!(
"Position 3 must be 'send' or 'post', got: '{}'",
other
)));
}
};
}
}
Err(_) => {
mode_send = match args[1] {
"post" => false,
"send" => true,
other => {
return Err(ScriptError::ParseError(format!(
"Position 2 must be a number (delay) or 'send'/'post' (mode), got: '{}'",
other
)));
}
};
}
}
}
if mode_send {
let key_down_input = keyboard_input::build_key_down_input(vk as u8, extended);
let key_up_input = keyboard_input::build_key_up_input(vk as u8, extended);
Ok(KeyParams::SendClick(KeyClickParams {
key_down_input,
key_up_input,
delay_ms,
}))
} else {
Ok(KeyParams::PostClick(KeyPostClickParams {
vk_code: vk as u8,
scan_code,
delay_ms,
}))
}
}
pub fn parse_key_down_args(args: &[&str]) -> Result<KeyParams, ScriptError> {
if args.is_empty() {
return Err(ScriptError::ParseError(
"Missing key name. Usage: key_down <name> [mode]".into(),
));
}
let vk = key_code(args[0]);
if vk == 0 {
return Err(ScriptError::ParseError(format!(
"Unknown key name: '{}'",
args[0]
)));
}
let scan_code = crate::get_scan_code(vk);
let extended = crate::utils::key_code::is_extended_key(vk as u8);
let mut mode_send = true;
if args.len() > 1 {
mode_send = match args[1] {
"post" => false,
"send" => true,
other => {
return Err(ScriptError::ParseError(format!(
"Position 2 must be 'send' or 'post', got: '{}'",
other
)));
}
};
}
if mode_send {
let input = keyboard_input::build_key_down_input(vk as u8, extended);
Ok(KeyParams::SendDown(KeyDownParams { input }))
} else {
Ok(KeyParams::PostDown(KeyPostDownUpParams {
vk_code: vk as u8,
scan_code,
}))
}
}
pub fn parse_key_up_args(args: &[&str]) -> Result<KeyParams, ScriptError> {
if args.is_empty() {
return Err(ScriptError::ParseError(
"Missing key name. Usage: key_up <name> [mode]".into(),
));
}
let vk = key_code(args[0]);
if vk == 0 {
return Err(ScriptError::ParseError(format!(
"Unknown key name: '{}'",
args[0]
)));
}
let scan_code = crate::get_scan_code(vk);
let extended = crate::utils::key_code::is_extended_key(vk as u8);
let mut mode_send = true;
if args.len() > 1 {
mode_send = match args[1] {
"post" => false,
"send" => true,
other => {
return Err(ScriptError::ParseError(format!(
"Position 2 must be 'send' or 'post', got: '{}'",
other
)));
}
};
}
if mode_send {
let input = keyboard_input::build_key_up_input(vk as u8, extended);
Ok(KeyParams::SendUp(KeyUpParams { input }))
} else {
Ok(KeyParams::PostUp(KeyPostDownUpParams {
vk_code: vk as u8,
scan_code,
}))
}
}