use crate::keyboard::keyboard_input;
use crate::keyboard::keyboard_message;
use crate::script_engine::instruction::{
InstructionData, InstructionHandler, InstructionMetadata, ScriptError,
};
use crate::script_engine::VMContext;
use crate::scripts_builtin::keyboard::KeyParams;
use crate::utils::sleep_ms;
pub struct KeyClickHandler;
impl InstructionHandler for KeyClickHandler {
fn name(&self) -> &str {
"key"
}
fn parse(&self, args: &[&str]) -> Result<InstructionData, ScriptError> {
let params = crate::scripts_builtin::keyboard::parse_key_click_args(args)?;
Ok(InstructionData::Custom(Box::new(params)))
}
fn execute(
&self,
vm: &mut VMContext,
data: &InstructionData,
_metadata: Option<&InstructionMetadata>,
) -> Result<(), ScriptError> {
let params = data.extract_custom::<KeyParams>("Invalid key parameters")?;
match params {
KeyParams::SendClick(p) => {
keyboard_input::execute_single_input(&p.key_down_input).map_err(|e| {
ScriptError::ExecutionError(format!("Key down failed: {:?}", e))
})?;
if p.delay_ms > 0 {
sleep_ms(p.delay_ms);
}
keyboard_input::execute_single_input(&p.key_up_input).map_err(|e| {
ScriptError::ExecutionError(format!("Key up failed: {:?}", e))
})?;
}
KeyParams::PostClick(p) => {
let hwnd = vm.process.hwnd.ok_or_else(|| {
ScriptError::ExecutionError(
"PostMessage mode requires hwnd to be set via process.set_hwnd()".into(),
)
})?;
keyboard_message::post_key_down_atomic(hwnd, p.vk_code, p.scan_code)
.map_err(|e| {
ScriptError::ExecutionError(format!("PostMessage key down failed: {:?}", e))
})?;
if p.delay_ms > 0 {
sleep_ms(p.delay_ms);
}
keyboard_message::post_key_up_atomic(hwnd, p.vk_code, p.scan_code)
.map_err(|e| {
ScriptError::ExecutionError(format!("PostMessage key up failed: {:?}", e))
})?;
}
_ => {
return Err(ScriptError::ExecutionError(
"Invalid key parameters for click".into(),
));
}
}
Ok(())
}
}