diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs
index 1d4bd7f..724d4b2 100644
--- a/src/keyboard/mod.rs
+++ b/src/keyboard/mod.rs
@@ -1,4 +1,10 @@
-pub enum KeyboardKey {
+#[cfg(target_os = "windows")]
+mod windows;
+#[cfg(target_os = "windows")]
+pub use crate::keyboard::windows::*;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum Key {
Escape,
Digit0,
Digit1,
@@ -73,6 +79,7 @@ pub enum KeyboardKey {
NumpadAdd,
NumpadSubtract,
NumpadMultiply,
+ NumpadDivide,
NumpadDecimal,
NumpadEqual,
NumpadComma,
@@ -115,7 +122,11 @@ pub enum KeyboardKey {
Delete,
MetaLeft,
MetaRight,
- ContextMenu,
+}
+
+pub enum KeyboardState {
+ Press,
+ Release,
}
pub struct Keyboard;
diff --git a/src/keyboard/windows/mod.rs b/src/keyboard/windows/mod.rs
index efce1dd..1003a60 100644
--- a/src/keyboard/windows/mod.rs
+++ b/src/keyboard/windows/mod.rs
@@ -1 +1,178 @@
-impl Keyboard {}
+use std::mem::{size_of, transmute_copy};
+use winapi::ctypes::c_int;
+use winapi::shared::minwindef::WORD;
+use winapi::um::winuser::{
+ GetAsyncKeyState, MapVirtualKeyW, SendInput, INPUT, INPUT_KEYBOARD, KEYBDINPUT, KEYEVENTF_KEYUP,
+ KEYEVENTF_SCANCODE, LPINPUT,
+};
+
+use crate::keyboard::{Key, Keyboard};
+
+impl Keyboard {
+ pub fn press(key: Key) {
+ let dw_flags = KEYEVENTF_SCANCODE;
+
+ let mut input = INPUT {
+ type_: INPUT_KEYBOARD,
+ u: unsafe {
+ transmute_copy(&KEYBDINPUT {
+ wVk: 0,
+ wScan: Self::key_to_scancode(key),
+ dwFlags: dw_flags,
+ time: 0,
+ dwExtraInfo: 0,
+ })
+ },
+ };
+ unsafe { SendInput(1, &mut input as LPINPUT, size_of::() as c_int) };
+ }
+
+ pub fn release(key: Key) {
+ let dw_flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
+
+ let mut input = INPUT {
+ type_: INPUT_KEYBOARD,
+ u: unsafe {
+ transmute_copy(&KEYBDINPUT {
+ wVk: 0,
+ wScan: Self::key_to_scancode(key),
+ dwFlags: dw_flags,
+ time: 0,
+ dwExtraInfo: 0,
+ })
+ },
+ };
+ unsafe { SendInput(1, &mut input as LPINPUT, size_of::() as c_int) };
+ }
+
+ pub fn pressed(key: Key) -> bool {
+ (unsafe { GetAsyncKeyState(Self::key_2_virtual_key(key) as i32) } >> 15) != 0
+ }
+
+ fn key_to_scancode(key: Key) -> u16 {
+ let vk = Self::key_2_virtual_key(key);
+ unsafe { MapVirtualKeyW(vk as u32, 0) as u16 }
+ }
+
+ fn key_2_virtual_key(key: Key) -> WORD {
+ match key {
+ Key::Digit0 => 0x30,
+ Key::Digit1 => 0x31,
+ Key::Digit2 => 0x32,
+ Key::Digit3 => 0x33,
+ Key::Digit4 => 0x34,
+ Key::Digit5 => 0x35,
+ Key::Digit6 => 0x36,
+ Key::Digit7 => 0x37,
+ Key::Digit8 => 0x38,
+ Key::Digit9 => 0x39,
+ Key::KeyA => 0x41,
+ Key::KeyB => 0x42,
+ Key::KeyC => 0x43,
+ Key::KeyD => 0x44,
+ Key::KeyE => 0x45,
+ Key::KeyF => 0x46,
+ Key::KeyG => 0x47,
+ Key::KeyH => 0x48,
+ Key::KeyI => 0x49,
+ Key::KeyJ => 0x4A,
+ Key::KeyK => 0x4B,
+ Key::KeyL => 0x4C,
+ Key::KeyM => 0x4D,
+ Key::KeyN => 0x4E,
+ Key::KeyO => 0x4F,
+ Key::KeyP => 0x50,
+ Key::KeyQ => 0x51,
+ Key::KeyR => 0x52,
+ Key::KeyS => 0x53,
+ Key::KeyT => 0x54,
+ Key::KeyU => 0x55,
+ Key::KeyV => 0x56,
+ Key::KeyW => 0x57,
+ Key::KeyX => 0x58,
+ Key::KeyY => 0x59,
+ Key::KeyZ => 0x5A,
+ Key::F1 => 0x70,
+ Key::F2 => 0x71,
+ Key::F3 => 0x72,
+ Key::F4 => 0x73,
+ Key::F5 => 0x74,
+ Key::F6 => 0x75,
+ Key::F7 => 0x76,
+ Key::F8 => 0x77,
+ Key::F9 => 0x78,
+ Key::F10 => 0x79,
+ Key::F11 => 0x7A,
+ Key::F12 => 0x7B,
+ Key::F13 => 0x7C,
+ Key::F14 => 0x7D,
+ Key::F15 => 0x7E,
+ Key::F16 => 0x7F,
+ Key::F17 => 0x80,
+ Key::F18 => 0x81,
+ Key::F19 => 0x82,
+ Key::F20 => 0x83,
+ Key::F21 => 0x84,
+ Key::F22 => 0x85,
+ Key::F23 => 0x86,
+ Key::F24 => 0x87,
+ Key::Numpad0 => 0x60,
+ Key::Numpad1 => 0x61,
+ Key::Numpad2 => 0x62,
+ Key::Numpad3 => 0x63,
+ Key::Numpad4 => 0x64,
+ Key::Numpad5 => 0x65,
+ Key::Numpad6 => 0x66,
+ Key::Numpad7 => 0x67,
+ Key::Numpad8 => 0x68,
+ Key::Numpad9 => 0x69,
+ Key::NumpadAdd => 0x6B, // Add
+ Key::NumpadSubtract => 0x6D, // Subtract
+ Key::NumpadMultiply => 0x6A, // Multiply
+ Key::NumpadDivide => 0x6F, // Divide
+ Key::NumpadDecimal => 0x6E, // Decimal
+ Key::NumpadEqual => '=' as u16,
+ Key::NumpadComma => ',' as u16,
+ Key::NumpadEnter => 0x0D,
+ Key::NumLock => 0x90,
+ Key::Minus => '-' as u16,
+ Key::Equal => '=' as u16,
+ Key::BracketLeft => '{' as u16,
+ Key::BracketRight => '}' as u16,
+ Key::Semicolon => ';' as u16,
+ Key::Quote => '\'' as u16,
+ Key::Backquote => '`' as u16,
+ Key::Backslash => '\\' as u16,
+ Key::Comma => ',' as u16,
+ Key::Period => '~' as u16,
+ Key::Slash => '/' as u16,
+ Key::Escape => 0x1B,
+ Key::Enter => 0x0D,
+ Key::Backspace => 0x08,
+ Key::Tab => 0x09,
+ Key::Space => 0x20,
+ Key::CapsLock => 0x14,
+ Key::ShiftLeft => 0xA0,
+ Key::ShiftRight => 0xA1,
+ Key::ControlLeft => 0xA2,
+ Key::ControlRight => 0xA3,
+ Key::AltLeft => 0xA4,
+ Key::AltRight => 0xA5,
+ Key::Pause => 0x13,
+ Key::ScrollLock => 0x91,
+ Key::PrintScreen => 0x2C,
+ Key::ArrowLeft => 0x25,
+ Key::ArrowUp => 0x26,
+ Key::ArrowRight => 0x27,
+ Key::ArrowDown => 0x28,
+ Key::PageUp => 0x21,
+ Key::PageDown => 0x22,
+ Key::Home => 0x24,
+ Key::End => 0x23,
+ Key::Insert => 0x2D,
+ Key::Delete => 0x2E,
+ Key::MetaLeft => 0x5B,
+ Key::MetaRight => 0x5C,
+ }
+ }
+}
diff --git a/src/mouse/windows/mod.rs b/src/mouse/windows/mod.rs
index e009926..6736ae9 100644
--- a/src/mouse/windows/mod.rs
+++ b/src/mouse/windows/mod.rs
@@ -12,7 +12,7 @@ use winapi::um::winuser::{
use crate::mouse::{Button, ButtonState, Mouse};
impl Mouse {
- pub fn move_to(absolute: bool, dx: i32, dy: i32) {
+ pub fn move_to(dx: i32, dy: i32) {
let width = unsafe { GetSystemMetrics(SM_CXVIRTUALSCREEN) };
let height = unsafe { GetSystemMetrics(SM_CYVIRTUALSCREEN) };
if width == 0 || height == 0 {
@@ -21,11 +21,8 @@ impl Mouse {
let pressed_left = Self::pressed(Button::Left);
let pressed_right = Self::pressed(Button::Right);
let pressed_middle = Self::pressed(Button::Middle);
- let mut dw_flags = MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
+ let mut dw_flags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
- if absolute {
- dw_flags = dw_flags | MOUSEEVENTF_ABSOLUTE;
- }
if pressed_left {
dw_flags = dw_flags | MOUSEEVENTF_LEFTDOWN;
}