2 releases
Uses new Rust 2024
new 0.1.1 | Mar 19, 2025 |
---|---|
0.1.0 | Mar 19, 2025 |
#62 in Windows APIs
34KB
583 lines
Utf-8 String to Windows Virtual Key Codes
A simple library that translates the following utf-8/ascii characters [a-zA-Z0-9`~!@#$%^&*()-_=+[{]}|;:'",<.>?]
into keystrokes for Windows computers with no dependencies.
Example Usage
use utf8_to_windows_vkc::Utf8KeyMapper;
fn main() {
let key_mapper = Utf8KeyMapper::new(); // create api structure
// unwrap keystrokes, returns error if map does not exists or invalid character
let r = key_mapper.to_keystrokes("Hello, World!").unwrap();
// Call your win32 implementation
send_keystrokes(&r);
}
Then define a function using your preferred win32 rust library/approach to send keystrokes like below:
use std::thread;
use std::time::Duration;
use winapi::ctypes::c_int;
use winapi::um::winuser::{INPUT_u, SendInput, INPUT, INPUT_KEYBOARD, KEYBDINPUT, KEYEVENTF_KEYUP, VK_SHIFT};
static INPUT_SIZE: c_int = size_of::<INPUT>() as c_int;
/// example impl using win32's SendInput function
fn send_keystrokes(keys: &Vec<u8>) {
let len = keys.len();
let mut is_shifting= false;
for i in 0..len { // iter over keys
// create windows input union structure
let mut input_u: INPUT_u = unsafe { std::mem::zeroed() };
let mut dw_flags = 0;
// check if current key is the shifting key, then toggle
if keys[i] as c_int == VK_SHIFT {
if is_shifting { // currently shifting, so release
is_shifting = false;
dw_flags = KEYEVENTF_KEYUP
} else { // start shifting
is_shifting = true; // update state that we are now shifting
}
}
unsafe {
// attach our keystroke information
*input_u.ki_mut() = KEYBDINPUT {
wVk: keys[i] as u16,
wScan: 0,
dwFlags: dw_flags,
time: 0,
dwExtraInfo: 0,
};
}
// create main input structure
let mut input = INPUT {
type_: INPUT_KEYBOARD,
u: input_u
};
unsafe {
// Use win32's SendInput to simulate keystroke
if SendInput(1, &mut input, INPUT_SIZE) == 0 {
print!("At least one keystroke failed to be enqueued.");
}
}
// IMPORTANT: Example delay allowing receiving process to handle keystrokes before receiving more
thread::sleep(Duration::from_millis(50));
}
}
Translation Notes
Translating an ascii character to a Window's virtual-key-code requires additional logic because of Window's use of the shift
key.
Not all ascii characters have a key representation, meaning not everything can be translated. If translation fails, Result<T, E>
is returned.
For example, uppercase characters
[A-Z]
do not have a unique virtual key code, instead they depend on the usage of their lowercase variant in conjunction with the shift key. Therefore, to type 'A' you must simulate the shift key down, press the windows virtual key code for 'a' and then release the shift key.
Note: There will always be an even number of
shift
keys present in every vector as everyshift
press (down) will eventually have a correspondingshift
release (up). Think of it as curly brackets, opening always has a closing.