winapi-virtual-input 0.1.3

Crate for interacting with virtual devices using winapi
Documentation
use std::mem::{size_of, zeroed};
use virtual_input::keyboard::{Keyboard, KeyboardKey};
use winapi::um::winuser::{GetAsyncKeyState, *};

pub struct WinApiKeyboard {}

impl WinApiKeyboard {
    pub fn new() -> Self {
        WinApiKeyboard {}
    }
}

impl Keyboard for WinApiKeyboard {
    fn press(&self, key: KeyboardKey) -> bool {
        send_keyboard_input(key, false)
    }

    fn release(&self, key: KeyboardKey) -> bool {
        send_keyboard_input(key, true)
    }

    fn is_pressed(&self, key: KeyboardKey) -> bool {
        let virtual_key_code = get_virtual_key_code(key);
        let key_state = unsafe { GetAsyncKeyState(virtual_key_code) } as u16;

        // If the most significant bit is set, the key is pressed.
        key_state >> 15 == 1
    }
}

fn send_keyboard_input(key: KeyboardKey, release: bool) -> bool {
    unsafe {
        let mut input = INPUT {
            type_: INPUT_KEYBOARD,
            u: zeroed(),
        };

        let flags = if release { KEYEVENTF_KEYUP } else { 0 };

        *input.u.ki_mut() = KEYBDINPUT {
            wVk: get_virtual_key_code(key) as u16,
            wScan: 0,
            dwFlags: flags,
            time: 0,
            dwExtraInfo: 0,
        };

        SendInput(1, &mut input, size_of::<INPUT>() as i32) == 1
    }
}

fn get_virtual_key_code(key: KeyboardKey) -> i32 {
    return match key {
        KeyboardKey::A => 0x41,
        KeyboardKey::B => 0x42,
        KeyboardKey::C => 0x43,
        KeyboardKey::D => 0x44,
        KeyboardKey::E => 0x45,
        KeyboardKey::F => 0x46,
        KeyboardKey::G => 0x47,
        KeyboardKey::H => 0x48,
        KeyboardKey::I => 0x49,
        KeyboardKey::J => 0x4A,
        KeyboardKey::K => 0x4B,
        KeyboardKey::L => 0x4C,
        KeyboardKey::M => 0x4D,
        KeyboardKey::N => 0x4E,
        KeyboardKey::O => 0x4F,
        KeyboardKey::P => 0x50,
        KeyboardKey::Q => 0x51,
        KeyboardKey::R => 0x52,
        KeyboardKey::S => 0x53,
        KeyboardKey::T => 0x54,
        KeyboardKey::U => 0x55,
        KeyboardKey::V => 0x56,
        KeyboardKey::W => 0x57,
        KeyboardKey::X => 0x58,
        KeyboardKey::Y => 0x59,
        KeyboardKey::Z => 0x5A,
        KeyboardKey::Num0 => 0x30,
        KeyboardKey::Num1 => 0x31,
        KeyboardKey::Num2 => 0x32,
        KeyboardKey::Num3 => 0x33,
        KeyboardKey::Num4 => 0x34,
        KeyboardKey::Num5 => 0x35,
        KeyboardKey::Num6 => 0x36,
        KeyboardKey::Num7 => 0x37,
        KeyboardKey::Num8 => 0x38,
        KeyboardKey::Num9 => 0x39,
        KeyboardKey::Enter => VK_RETURN,
        KeyboardKey::Esc => VK_ESCAPE,
        KeyboardKey::Del => VK_DELETE,
        KeyboardKey::Tab => VK_TAB,
        KeyboardKey::Space => VK_SPACE,
        KeyboardKey::LeftControl => VK_LCONTROL,
        KeyboardKey::LeftShift => VK_LSHIFT,
        KeyboardKey::LeftAlt => VK_LMENU,
        KeyboardKey::LeftWindows => VK_LWIN,
        KeyboardKey::RightControl => VK_RCONTROL,
        KeyboardKey::RightShift => VK_RSHIFT,
        KeyboardKey::RightAlt => VK_RMENU,
        KeyboardKey::RightWindows => VK_RWIN,
    };
}