refactoring

This commit is contained in:
crusader 2020-12-17 00:04:14 +09:00
parent 02355fa511
commit fbf3946f59
3 changed files with 351 additions and 379 deletions

View File

@ -5,13 +5,8 @@ pub use crate::windows::*;
use crate::keyboard::Key;
use crate::mouse::Button;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::{
collections::hash_map::HashMap,
sync::{Arc, Mutex},
time::SystemTime,
};
pub mod keyboard;
pub mod mouse;
@ -31,61 +26,61 @@ pub enum EventType {
MouseMoveTo { x: f64, y: f64 },
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Event {
pub time: SystemTime,
pub event_type: EventType,
}
// #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
// pub struct Event {
// pub time: SystemTime,
// pub event_type: EventType,
// }
pub enum BlockInput {
Block,
DontBlock,
}
// pub enum BlockInput {
// Block,
// DontBlock,
// }
pub enum Bind {
NormalBind(BindHandler),
BlockBind(BlockBindHandler),
BlockableBind(BlockableBindHandler),
}
// pub enum Bind {
// NormalBind(BindHandler),
// BlockBind(BlockBindHandler),
// BlockableBind(BlockableBindHandler),
// }
pub type BindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockBindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockableBindHandler = Arc<dyn Fn(Event) -> BlockInput + Send + Sync + 'static>;
// pub type BindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
// pub type BlockBindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
// pub type BlockableBindHandler = Arc<dyn Fn(Event) -> BlockInput + Send + Sync + 'static>;
pub type EventBindMap = HashMap<EventListenType, Bind>;
pub static EVENT_BINDS: Lazy<Mutex<EventBindMap>> = Lazy::new(|| Mutex::new(EventBindMap::new()));
// pub type EventBindMap = HashMap<EventListenType, Bind>;
// pub static EVENT_BINDS: Lazy<Mutex<EventBindMap>> = Lazy::new(|| Mutex::new(EventBindMap::new()));
pub struct Robot;
impl Robot {
pub fn bind<F: Fn(Event) + Send + Sync + 'static>(listen_type: EventListenType, callback: F) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::NormalBind(Arc::new(callback)));
}
// impl Robot {
// pub fn bind<F: Fn(Event) + Send + Sync + 'static>(listen_type: EventListenType, callback: F) {
// EVENT_BINDS
// .lock()
// .unwrap()
// .insert(listen_type, Bind::NormalBind(Arc::new(callback)));
// }
pub fn block_bind<F: Fn(Event) + Send + Sync + 'static>(
listen_type: EventListenType,
callback: F,
) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::BlockBind(Arc::new(callback)));
}
// pub fn block_bind<F: Fn(Event) + Send + Sync + 'static>(
// listen_type: EventListenType,
// callback: F,
// ) {
// EVENT_BINDS
// .lock()
// .unwrap()
// .insert(listen_type, Bind::BlockBind(Arc::new(callback)));
// }
pub fn blockable_bind<F: Fn(Event) -> BlockInput + Send + Sync + 'static>(
listen_type: EventListenType,
callback: F,
) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::BlockableBind(Arc::new(callback)));
}
// pub fn blockable_bind<F: Fn(Event) -> BlockInput + Send + Sync + 'static>(
// listen_type: EventListenType,
// callback: F,
// ) {
// EVENT_BINDS
// .lock()
// .unwrap()
// .insert(listen_type, Bind::BlockableBind(Arc::new(callback)));
// }
pub fn unbind(listen_type: EventListenType) {
EVENT_BINDS.lock().unwrap().remove(&listen_type);
}
}
// pub fn unbind(listen_type: EventListenType) {
// EVENT_BINDS.lock().unwrap().remove(&listen_type);
// }
// }

View File

@ -1,25 +1,15 @@
use crate::windows;
use crate::{Bind, BlockInput, Event, EventListenType, EventType, Key, Robot, EVENT_BINDS};
use crate::{Key, Robot};
use once_cell::sync::Lazy;
use std::{
collections::HashMap,
mem::{size_of, transmute_copy},
ptr::null_mut,
sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
};
use winapi::ctypes::c_int;
use winapi::shared::minwindef::{LPARAM, LRESULT, WORD, WPARAM};
use winapi::shared::windef::HHOOK__;
use winapi::shared::minwindef::WORD;
use winapi::um::winuser::{
CallNextHookEx, GetAsyncKeyState, GetKeyState, MapVirtualKeyW, SendInput, HC_ACTION, INPUT,
INPUT_KEYBOARD, KBDLLHOOKSTRUCT, KEYBDINPUT, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, LPINPUT,
WH_KEYBOARD_LL, WM_KEYDOWN, WM_KEYUP,
GetAsyncKeyState, GetKeyState, MapVirtualKeyW, SendInput, INPUT, INPUT_KEYBOARD, KEYBDINPUT,
KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, LPINPUT,
};
static KEY_2_VK_MAP: Lazy<HashMap<Key, WORD>> = Lazy::new(|| {
@ -144,151 +134,151 @@ static KEY_2_VK_MAP: Lazy<HashMap<Key, WORD>> = Lazy::new(|| {
m
});
static VK_2_KEY_MAP: Lazy<HashMap<WORD, Key>> = Lazy::new(|| {
let mut m = HashMap::new();
m.insert(0x30, Key::Digit0);
m.insert(0x31, Key::Digit1);
m.insert(0x32, Key::Digit2);
m.insert(0x33, Key::Digit3);
m.insert(0x34, Key::Digit4);
m.insert(0x35, Key::Digit5);
m.insert(0x36, Key::Digit6);
m.insert(0x37, Key::Digit7);
m.insert(0x38, Key::Digit8);
m.insert(0x39, Key::Digit9);
m.insert(0x41, Key::KeyA);
m.insert(0x42, Key::KeyB);
m.insert(0x43, Key::KeyC);
m.insert(0x44, Key::KeyD);
m.insert(0x45, Key::KeyE);
m.insert(0x46, Key::KeyF);
m.insert(0x47, Key::KeyG);
m.insert(0x48, Key::KeyH);
m.insert(0x49, Key::KeyI);
m.insert(0x4A, Key::KeyJ);
m.insert(0x4B, Key::KeyK);
m.insert(0x4C, Key::KeyL);
m.insert(0x4D, Key::KeyM);
m.insert(0x4E, Key::KeyN);
m.insert(0x4F, Key::KeyO);
m.insert(0x50, Key::KeyP);
m.insert(0x51, Key::KeyQ);
m.insert(0x52, Key::KeyR);
m.insert(0x53, Key::KeyS);
m.insert(0x54, Key::KeyT);
m.insert(0x55, Key::KeyU);
m.insert(0x56, Key::KeyV);
m.insert(0x57, Key::KeyW);
m.insert(0x58, Key::KeyX);
m.insert(0x59, Key::KeyY);
m.insert(0x5A, Key::KeyZ);
m.insert(0x70, Key::F1);
m.insert(0x71, Key::F2);
m.insert(0x72, Key::F3);
m.insert(0x73, Key::F4);
m.insert(0x74, Key::F5);
m.insert(0x75, Key::F6);
m.insert(0x76, Key::F7);
m.insert(0x77, Key::F8);
m.insert(0x78, Key::F9);
m.insert(0x79, Key::F10);
m.insert(0x7A, Key::F11);
m.insert(0x7B, Key::F12);
m.insert(0x7C, Key::F13);
m.insert(0x7D, Key::F14);
m.insert(0x7E, Key::F15);
m.insert(0x7F, Key::F16);
m.insert(0x80, Key::F17);
m.insert(0x81, Key::F18);
m.insert(0x82, Key::F19);
m.insert(0x83, Key::F20);
m.insert(0x84, Key::F21);
m.insert(0x85, Key::F22);
m.insert(0x86, Key::F23);
m.insert(0x87, Key::F24);
m.insert(0x60, Key::Numpad0);
m.insert(0x61, Key::Numpad1);
m.insert(0x62, Key::Numpad2);
m.insert(0x63, Key::Numpad3);
m.insert(0x64, Key::Numpad4);
m.insert(0x65, Key::Numpad5);
m.insert(0x66, Key::Numpad6);
m.insert(0x67, Key::Numpad7);
m.insert(0x68, Key::Numpad8);
m.insert(0x69, Key::Numpad9);
m.insert(0x6B, Key::NumpadAdd); // Add
m.insert(0x6D, Key::NumpadSubtract); // Subtract
m.insert(0x6A, Key::NumpadMultiply); // Multiply
m.insert(0x6F, Key::NumpadDivide); // Divide
m.insert(0x6E, Key::NumpadDecimal); // Decimal
m.insert(0x0D, Key::NumpadEnter);
m.insert(0x90, Key::NumLock);
m.insert('-' as u16, Key::Minus);
m.insert('=' as u16, Key::Equal);
m.insert('{' as u16, Key::BracketLeft);
m.insert('}' as u16, Key::BracketRight);
m.insert(';' as u16, Key::Semicolon);
m.insert('\'' as u16, Key::Quote);
m.insert('`' as u16, Key::Backquote);
m.insert('\\' as u16, Key::Backslash);
m.insert(',' as u16, Key::Comma);
m.insert('~' as u16, Key::Period);
m.insert('/' as u16, Key::Slash);
m.insert(0x1B, Key::Escape);
m.insert(0x0D, Key::Enter);
m.insert(0x08, Key::Backspace);
m.insert(0x09, Key::Tab);
m.insert(0x20, Key::Space);
m.insert(0x14, Key::CapsLock);
m.insert(0xA0, Key::ShiftLeft);
m.insert(0xA1, Key::ShiftRight);
m.insert(0xA2, Key::ControlLeft);
m.insert(0xA3, Key::ControlRight);
m.insert(0xA4, Key::AltLeft);
m.insert(0xA5, Key::AltRight);
m.insert(0x13, Key::Pause);
m.insert(0x91, Key::ScrollLock);
m.insert(0x2C, Key::PrintScreen);
m.insert(0x25, Key::ArrowLeft);
m.insert(0x26, Key::ArrowUp);
m.insert(0x27, Key::ArrowRight);
m.insert(0x28, Key::ArrowDown);
m.insert(0x21, Key::PageUp);
m.insert(0x22, Key::PageDown);
m.insert(0x24, Key::Home);
m.insert(0x23, Key::End);
m.insert(0x2D, Key::Insert);
m.insert(0x2E, Key::Delete);
m.insert(0x5B, Key::MetaLeft);
m.insert(0x5C, Key::MetaRight);
m
});
// static VK_2_KEY_MAP: Lazy<HashMap<WORD, Key>> = Lazy::new(|| {
// let mut m = HashMap::new();
// m.insert(0x30, Key::Digit0);
// m.insert(0x31, Key::Digit1);
// m.insert(0x32, Key::Digit2);
// m.insert(0x33, Key::Digit3);
// m.insert(0x34, Key::Digit4);
// m.insert(0x35, Key::Digit5);
// m.insert(0x36, Key::Digit6);
// m.insert(0x37, Key::Digit7);
// m.insert(0x38, Key::Digit8);
// m.insert(0x39, Key::Digit9);
// m.insert(0x41, Key::KeyA);
// m.insert(0x42, Key::KeyB);
// m.insert(0x43, Key::KeyC);
// m.insert(0x44, Key::KeyD);
// m.insert(0x45, Key::KeyE);
// m.insert(0x46, Key::KeyF);
// m.insert(0x47, Key::KeyG);
// m.insert(0x48, Key::KeyH);
// m.insert(0x49, Key::KeyI);
// m.insert(0x4A, Key::KeyJ);
// m.insert(0x4B, Key::KeyK);
// m.insert(0x4C, Key::KeyL);
// m.insert(0x4D, Key::KeyM);
// m.insert(0x4E, Key::KeyN);
// m.insert(0x4F, Key::KeyO);
// m.insert(0x50, Key::KeyP);
// m.insert(0x51, Key::KeyQ);
// m.insert(0x52, Key::KeyR);
// m.insert(0x53, Key::KeyS);
// m.insert(0x54, Key::KeyT);
// m.insert(0x55, Key::KeyU);
// m.insert(0x56, Key::KeyV);
// m.insert(0x57, Key::KeyW);
// m.insert(0x58, Key::KeyX);
// m.insert(0x59, Key::KeyY);
// m.insert(0x5A, Key::KeyZ);
// m.insert(0x70, Key::F1);
// m.insert(0x71, Key::F2);
// m.insert(0x72, Key::F3);
// m.insert(0x73, Key::F4);
// m.insert(0x74, Key::F5);
// m.insert(0x75, Key::F6);
// m.insert(0x76, Key::F7);
// m.insert(0x77, Key::F8);
// m.insert(0x78, Key::F9);
// m.insert(0x79, Key::F10);
// m.insert(0x7A, Key::F11);
// m.insert(0x7B, Key::F12);
// m.insert(0x7C, Key::F13);
// m.insert(0x7D, Key::F14);
// m.insert(0x7E, Key::F15);
// m.insert(0x7F, Key::F16);
// m.insert(0x80, Key::F17);
// m.insert(0x81, Key::F18);
// m.insert(0x82, Key::F19);
// m.insert(0x83, Key::F20);
// m.insert(0x84, Key::F21);
// m.insert(0x85, Key::F22);
// m.insert(0x86, Key::F23);
// m.insert(0x87, Key::F24);
// m.insert(0x60, Key::Numpad0);
// m.insert(0x61, Key::Numpad1);
// m.insert(0x62, Key::Numpad2);
// m.insert(0x63, Key::Numpad3);
// m.insert(0x64, Key::Numpad4);
// m.insert(0x65, Key::Numpad5);
// m.insert(0x66, Key::Numpad6);
// m.insert(0x67, Key::Numpad7);
// m.insert(0x68, Key::Numpad8);
// m.insert(0x69, Key::Numpad9);
// m.insert(0x6B, Key::NumpadAdd); // Add
// m.insert(0x6D, Key::NumpadSubtract); // Subtract
// m.insert(0x6A, Key::NumpadMultiply); // Multiply
// m.insert(0x6F, Key::NumpadDivide); // Divide
// m.insert(0x6E, Key::NumpadDecimal); // Decimal
// m.insert(0x0D, Key::NumpadEnter);
// m.insert(0x90, Key::NumLock);
// m.insert('-' as u16, Key::Minus);
// m.insert('=' as u16, Key::Equal);
// m.insert('{' as u16, Key::BracketLeft);
// m.insert('}' as u16, Key::BracketRight);
// m.insert(';' as u16, Key::Semicolon);
// m.insert('\'' as u16, Key::Quote);
// m.insert('`' as u16, Key::Backquote);
// m.insert('\\' as u16, Key::Backslash);
// m.insert(',' as u16, Key::Comma);
// m.insert('~' as u16, Key::Period);
// m.insert('/' as u16, Key::Slash);
// m.insert(0x1B, Key::Escape);
// m.insert(0x0D, Key::Enter);
// m.insert(0x08, Key::Backspace);
// m.insert(0x09, Key::Tab);
// m.insert(0x20, Key::Space);
// m.insert(0x14, Key::CapsLock);
// m.insert(0xA0, Key::ShiftLeft);
// m.insert(0xA1, Key::ShiftRight);
// m.insert(0xA2, Key::ControlLeft);
// m.insert(0xA3, Key::ControlRight);
// m.insert(0xA4, Key::AltLeft);
// m.insert(0xA5, Key::AltRight);
// m.insert(0x13, Key::Pause);
// m.insert(0x91, Key::ScrollLock);
// m.insert(0x2C, Key::PrintScreen);
// m.insert(0x25, Key::ArrowLeft);
// m.insert(0x26, Key::ArrowUp);
// m.insert(0x27, Key::ArrowRight);
// m.insert(0x28, Key::ArrowDown);
// m.insert(0x21, Key::PageUp);
// m.insert(0x22, Key::PageDown);
// m.insert(0x24, Key::Home);
// m.insert(0x23, Key::End);
// m.insert(0x2D, Key::Insert);
// m.insert(0x2E, Key::Delete);
// m.insert(0x5B, Key::MetaLeft);
// m.insert(0x5C, Key::MetaRight);
// m
// });
static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
// static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
impl Robot {
pub unsafe fn key_listen() -> Result<(), windows::HookError> {
if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback);
// pub unsafe fn key_listen() -> Result<(), windows::HookError> {
// if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
// let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback);
if r.is_err() {
return Err(windows::HookError::Keyboard(r.err().unwrap()));
}
}
// if r.is_err() {
// return Err(windows::HookError::Keyboard(r.err().unwrap()));
// }
// }
Ok(())
}
// Ok(())
// }
pub unsafe fn key_unlisten() -> Result<(), windows::HookError> {
if !KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::unhook(&*KEYBOARD_HHOOK);
if r.is_err() {
return Err(windows::HookError::Keyboard(r.err().unwrap()));
}
}
// pub unsafe fn key_unlisten() -> Result<(), windows::HookError> {
// if !KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
// let r = windows::unhook(&*KEYBOARD_HHOOK);
// if r.is_err() {
// return Err(windows::HookError::Keyboard(r.err().unwrap()));
// }
// }
Ok(())
}
// Ok(())
// }
pub fn key_press(key: Key) {
let dw_flags = KEYEVENTF_SCANCODE;
@ -339,63 +329,63 @@ impl Robot {
}
}
unsafe fn get_virtual_key(lpdata: isize) -> u32 {
let kb = *(lpdata as *const KBDLLHOOKSTRUCT);
kb.vkCode
}
// unsafe fn get_virtual_key(lpdata: isize) -> u32 {
// let kb = *(lpdata as *const KBDLLHOOKSTRUCT);
// kb.vkCode
// }
unsafe extern "system" fn key_raw_callback(
code: c_int,
w_param: WPARAM,
l_param: LPARAM,
) -> LRESULT {
if code == HC_ACTION {
let opt = match w_param as u32 {
WM_KEYDOWN => {
let code = Self::get_virtual_key(l_param);
match Self::virtual_key_2_key(code as u16) {
Some(k) => Some(EventType::KeyPress(k)),
None => None,
}
}
WM_KEYUP => {
let code = Self::get_virtual_key(l_param);
match Self::virtual_key_2_key(code as u16) {
Some(k) => Some(EventType::KeyRelease(k)),
None => None,
}
}
_ => None,
};
// unsafe extern "system" fn key_raw_callback(
// code: c_int,
// w_param: WPARAM,
// l_param: LPARAM,
// ) -> LRESULT {
// if code == HC_ACTION {
// let opt = match w_param as u32 {
// WM_KEYDOWN => {
// let code = Self::get_virtual_key(l_param);
// match Self::virtual_key_2_key(code as u16) {
// Some(k) => Some(EventType::KeyPress(k)),
// None => None,
// }
// }
// WM_KEYUP => {
// let code = Self::get_virtual_key(l_param);
// match Self::virtual_key_2_key(code as u16) {
// Some(k) => Some(EventType::KeyRelease(k)),
// None => None,
// }
// }
// _ => None,
// };
if let Some(event_type) = opt {
let event = Event {
event_type,
time: SystemTime::now(),
};
// if let Some(event_type) = opt {
// let event = Event {
// event_type,
// time: SystemTime::now(),
// };
if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind {
Bind::NormalBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
}
Bind::BlockBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
return 1;
}
Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) {
return 1;
}
}
}
}
}
}
CallNextHookEx(null_mut(), code, w_param, l_param)
}
// if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
// match bind {
// Bind::NormalBind(cb) => {
// let cb = Arc::clone(cb);
// spawn(move || cb(event));
// }
// Bind::BlockBind(cb) => {
// let cb = Arc::clone(cb);
// spawn(move || cb(event));
// return 1;
// }
// Bind::BlockableBind(cb) => {
// if let BlockInput::Block = cb(event) {
// return 1;
// }
// }
// }
// }
// }
// }
// CallNextHookEx(null_mut(), code, w_param, l_param)
// }
fn key_2_virtual_key(key: Key) -> Option<WORD> {
match KEY_2_VK_MAP.get(&key) {
@ -404,10 +394,10 @@ impl Robot {
}
}
fn virtual_key_2_key(virtual_key: WORD) -> Option<Key> {
match VK_2_KEY_MAP.get(&virtual_key) {
Some(v) => Some(*v),
None => None,
}
}
// fn virtual_key_2_key(virtual_key: WORD) -> Option<Key> {
// match VK_2_KEY_MAP.get(&virtual_key) {
// Some(v) => Some(*v),
// None => None,
// }
// }
}

View File

@ -1,55 +1,42 @@
use crate::windows;
use crate::{Bind, BlockInput, Button, Event, EventListenType, EventType, Robot, EVENT_BINDS};
use once_cell::sync::Lazy;
use std::{
mem::{size_of, transmute},
ptr::null_mut,
sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
};
use crate::{Button, EventType, Robot};
use std::mem::{size_of, transmute};
use winapi::ctypes::c_int;
use winapi::shared::minwindef::{DWORD, HIWORD, LPARAM, LRESULT, WPARAM};
use winapi::shared::windef::{HHOOK__, POINT};
use winapi::shared::minwindef::DWORD;
use winapi::shared::windef::POINT;
use winapi::um::winuser::{
CallNextHookEx, GetAsyncKeyState, GetCursorPos, GetSystemMetrics, SendInput, HC_ACTION, INPUT,
INPUT_MOUSE, LPINPUT, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN,
MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE,
MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK, MOUSEEVENTF_WHEEL,
MOUSEINPUT, MSLLHOOKSTRUCT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN,
SM_YVIRTUALSCREEN, VK_LBUTTON, VK_MBUTTON, VK_RBUTTON, VK_XBUTTON1, VK_XBUTTON2, WH_MOUSE_LL,
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEMOVE, WM_RBUTTONDOWN,
WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
GetAsyncKeyState, GetCursorPos, GetSystemMetrics, SendInput, INPUT, INPUT_MOUSE, LPINPUT,
MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP,
MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN,
MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK, MOUSEEVENTF_WHEEL, MOUSEINPUT, SM_CXVIRTUALSCREEN,
SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, VK_LBUTTON, VK_MBUTTON, VK_RBUTTON,
VK_XBUTTON1, VK_XBUTTON2,
};
static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
// static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
impl Robot {
pub unsafe fn mouse_listen() -> Result<(), windows::HookError> {
if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback);
// pub unsafe fn mouse_listen() -> Result<(), windows::HookError> {
// if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
// let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback);
if r.is_err() {
return Err(windows::HookError::Mouse(r.err().unwrap()));
}
}
// if r.is_err() {
// return Err(windows::HookError::Mouse(r.err().unwrap()));
// }
// }
Ok(())
}
// Ok(())
// }
pub unsafe fn mouse_unlisten() -> Result<(), windows::HookError> {
if !MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::unhook(&*MOUSE_HHOOK);
if r.is_err() {
return Err(windows::HookError::Mouse(r.err().unwrap()));
}
}
// pub unsafe fn mouse_unlisten() -> Result<(), windows::HookError> {
// if !MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
// let r = windows::unhook(&*MOUSE_HHOOK);
// if r.is_err() {
// return Err(windows::HookError::Mouse(r.err().unwrap()));
// }
// }
Ok(())
}
// Ok(())
// }
pub fn mouse_location() -> (i32, i32) {
let mut point = POINT { x: 0, y: 0 };
@ -169,79 +156,79 @@ impl Robot {
}
}
unsafe fn get_mouse_point(lpdata: isize) -> (i32, i32) {
let mouse = *(lpdata as *const MSLLHOOKSTRUCT);
(mouse.pt.x, mouse.pt.y)
}
// unsafe fn get_mouse_point(lpdata: isize) -> (i32, i32) {
// let mouse = *(lpdata as *const MSLLHOOKSTRUCT);
// (mouse.pt.x, mouse.pt.y)
// }
#[allow(non_snake_case)]
unsafe extern "system" fn mouse_raw_callback(
code: c_int,
w_param: WPARAM,
l_param: LPARAM,
) -> LRESULT {
if code == HC_ACTION {
let opt = match w_param as u32 {
WM_LBUTTONDOWN => Some(EventType::MousePress(Button::Left)),
WM_LBUTTONUP => Some(EventType::MouseRelease(Button::Left)),
WM_MBUTTONDOWN => Some(EventType::MousePress(Button::Middle)),
WM_MBUTTONUP => Some(EventType::MouseRelease(Button::Middle)),
WM_RBUTTONDOWN => Some(EventType::MousePress(Button::Right)),
WM_RBUTTONUP => Some(EventType::MouseRelease(Button::Right)),
WM_XBUTTONDOWN => {
let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
// #[allow(non_snake_case)]
// unsafe extern "system" fn mouse_raw_callback(
// code: c_int,
// w_param: WPARAM,
// l_param: LPARAM,
// ) -> LRESULT {
// if code == HC_ACTION {
// let opt = match w_param as u32 {
// WM_LBUTTONDOWN => Some(EventType::MousePress(Button::Left)),
// WM_LBUTTONUP => Some(EventType::MouseRelease(Button::Left)),
// WM_MBUTTONDOWN => Some(EventType::MousePress(Button::Middle)),
// WM_MBUTTONUP => Some(EventType::MouseRelease(Button::Middle)),
// WM_RBUTTONDOWN => Some(EventType::MousePress(Button::Right)),
// WM_RBUTTONUP => Some(EventType::MouseRelease(Button::Right)),
// WM_XBUTTONDOWN => {
// let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
match HIWORD(llhs.mouseData) {
XBUTTON1 => Some(EventType::MousePress(Button::X1)),
XBUTTON2 => Some(EventType::MousePress(Button::X2)),
_ => None,
}
}
WM_XBUTTONUP => {
let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
// match HIWORD(llhs.mouseData) {
// XBUTTON1 => Some(EventType::MousePress(Button::X1)),
// XBUTTON2 => Some(EventType::MousePress(Button::X2)),
// _ => None,
// }
// }
// WM_XBUTTONUP => {
// let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
match HIWORD(llhs.mouseData) {
XBUTTON1 => Some(EventType::MouseRelease(Button::X1)),
XBUTTON2 => Some(EventType::MouseRelease(Button::X2)),
_ => None,
}
}
WM_MOUSEMOVE => {
let (x, y) = Self::get_mouse_point(l_param);
Some(EventType::MouseMoveTo {
x: x as f64,
y: y as f64,
})
}
_ => None,
};
// match HIWORD(llhs.mouseData) {
// XBUTTON1 => Some(EventType::MouseRelease(Button::X1)),
// XBUTTON2 => Some(EventType::MouseRelease(Button::X2)),
// _ => None,
// }
// }
// WM_MOUSEMOVE => {
// let (x, y) = Self::get_mouse_point(l_param);
// Some(EventType::MouseMoveTo {
// x: x as f64,
// y: y as f64,
// })
// }
// _ => None,
// };
if let Some(event_type) = opt {
let event = Event {
event_type,
time: SystemTime::now(),
};
// if let Some(event_type) = opt {
// let event = Event {
// event_type,
// time: SystemTime::now(),
// };
if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind {
Bind::NormalBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
}
Bind::BlockBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
return 1;
}
Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) {
return 1;
}
}
}
}
}
}
CallNextHookEx(null_mut(), code, w_param, l_param)
}
// if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
// match bind {
// Bind::NormalBind(cb) => {
// let cb = Arc::clone(cb);
// spawn(move || cb(event));
// }
// Bind::BlockBind(cb) => {
// let cb = Arc::clone(cb);
// spawn(move || cb(event));
// return 1;
// }
// Bind::BlockableBind(cb) => {
// if let BlockInput::Block = cb(event) {
// return 1;
// }
// }
// }
// }
// }
// }
// CallNextHookEx(null_mut(), code, w_param, l_param)
// }
}