From this stackoverflow Virtual Key Codes are at: MSDN See also this stackoverflow on unicode to see how to send unicode.
Also this stackoverflow on sending to a specific window
We use ctypes to call to user32.
import ctypes
from ctypes import wintypes
import time
user32 = ctypes.WinDLL('user32', use_last_error=True)
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002
KEYEVENTF_UNICODE = 0x0004
KEYEVENTF_SCANCODE = 0x0008
MAPVK_VK_TO_VSC = 0
# msdn.microsoft.com/en-us/library/dd375731
VK_TAB = 0x09
VK_MENU = 0x12
# C struct definitions
wintypes.ULONG_PTR = wintypes.WPARAM
class MOUSEINPUT(ctypes.Structure):
_fields_ = (("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
class KEYBDINPUT(ctypes.Structure):
_fields_ = (("wVk", wintypes.WORD),
("wScan", wintypes.WORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
def __init__(self, *args, **kwds):
super(KEYBDINPUT, self).__init__(*args, **kwds)
# some programs use the scan code even if KEYEVENTF_SCANCODE
# isn't set in dwFflags, so attempt to map the correct code.
if not self.dwFlags & KEYEVENTF_UNICODE:
self.wScan = user32.MapVirtualKeyExW(self.wVk,
MAPVK_VK_TO_VSC, 0)
class HARDWAREINPUT(ctypes.Structure):
_fields_ = (("uMsg", wintypes.DWORD),
("wParamL", wintypes.WORD),
("wParamH", wintypes.WORD))
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = (("ki", KEYBDINPUT),
("mi", MOUSEINPUT),
("hi", HARDWAREINPUT))
_anonymous_ = ("_input",)
_fields_ = (("type", wintypes.DWORD),
("_input", _INPUT))
LPINPUT = ctypes.POINTER(INPUT)
def _check_count(result, func, args):
if result == 0:
raise ctypes.WinError(ctypes.get_last_error())
return args
user32.SendInput.errcheck = _check_count
user32.SendInput.argtypes = (wintypes.UINT, # nInputs
LPINPUT, # pInputs
ctypes.c_int) # cbSize
# Functions
def PressKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode,
dwFlags=KEYEVENTF_KEYUP))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def AltTab():
"""Press Alt+Tab and hold Alt key for 2 seconds
in order to see the overlay.
"""
PressKey(VK_MENU) # Alt
PressKey(VK_TAB) # Tab
ReleaseKey(VK_TAB) # Tab~
time.sleep(2)
ReleaseKey(VK_MENU) # Alt~
if __name__ == "__main__":
AltTab()
Unicode
From this stackoverflow
#include <vector>
#include <string>
void SendInputString(const std::wstring &str)
{
int len = str.length();
if (len == 0) return;
std::vector<INPUT> in(len*2);
ZeroMemory(&in[0], in.size()*sizeof(INPUT));
int i = 0, idx = 0;
while (i < len)
{
WORD ch = (WORD) str[i++];
if ((ch < 0xD800) || (ch > 0xDFFF))
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-1];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
else
{
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = ch;
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx].type = INPUT_KEYBOARD;
in[idx].ki.wScan = (WORD) str[i++];
in[idx].ki.dwFlags = KEYEVENTF_UNICODE;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
in[idx] = in[idx-2];
in[idx].ki.dwFlags |= KEYEVENTF_KEYUP;
++idx;
}
}
SendInput(in.size(), &in[0], sizeof(INPUT));
}
Sending To A Window
From this stackoverflow
int SendKeystrokesToNotepad( const TCHAR *const text )
{
INPUT *keystroke;
UINT i, character_count, keystrokes_to_send, keystrokes_sent;
HWND notepad;
assert( text != NULL );
//Get the handle of the Notepad window.
notepad = FindWindow( _T( "Notepad" ), NULL );
if( notepad == NULL )
return 0;
//Bring the Notepad window to the front.
if( !SetForegroundWindow( notepad ) )
return 0;
//Fill in the array of keystrokes to send.
character_count = _tcslen( text );
keystrokes_to_send = character_count * 2;
keystroke = new INPUT[ keystrokes_to_send ];
for( i = 0; i < character_count; ++i )
{
keystroke[ i * 2 ].type = INPUT_KEYBOARD;
keystroke[ i * 2 ].ki.wVk = 0;
keystroke[ i * 2 ].ki.wScan = text[ i ];
keystroke[ i * 2 ].ki.dwFlags = KEYEVENTF_UNICODE;
keystroke[ i * 2 ].ki.time = 0;
keystroke[ i * 2 ].ki.dwExtraInfo = GetMessageExtraInfo();
keystroke[ i * 2 + 1 ].type = INPUT_KEYBOARD;
keystroke[ i * 2 + 1 ].ki.wVk = 0;
keystroke[ i * 2 + 1 ].ki.wScan = text[ i ];
keystroke[ i * 2 + 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
keystroke[ i * 2 + 1 ].ki.time = 0;
keystroke[ i * 2 + 1 ].ki.dwExtraInfo = GetMessageExtraInfo();
}
//Send the keystrokes.
keystrokes_sent = SendInput( ( UINT )keystrokes_to_send, keystroke, sizeof( *keystroke ) );
delete [] keystroke;
return keystrokes_sent == keystrokes_to_send;
}
Key Codes
From MSDN linked above.
| VK_LBUTTON | 0x01 | Left mouse button |
| VK_RBUTTON | 0x02 | Right mouse button |
| VK_CANCEL | 0x03 | Control-break processing |
| VK_MBUTTON | 0x04 | Middle mouse button |
| VK_XBUTTON1 | 0x05 | X1 mouse button |
| VK_XBUTTON2 | 0x06 | X2 mouse button |
| - | 0x07 | Reserved |
| VK_BACK | 0x08 | BACKSPACE key |
| VK_TAB | 0x09 | TAB key |
| - | 0x0A-0B | Reserved |
| VK_CLEAR | 0x0C | CLEAR key |
| VK_RETURN | 0x0D | ENTER key |
| - | 0x0E-0F | Unassigned |
| VK_SHIFT | 0x10 | SHIFT key |
| VK_CONTROL | 0x11 | CTRL key |
| VK_MENU | 0x12 | ALT key |
| VK_PAUSE | 0x13 | PAUSE key |
| VK_CAPITAL | 0x14 | CAPS LOCK key |
| VK_KANA | 0x15 | IME Kana mode |
| VK_HANGUL | 0x15 | IME Hangul mode |
| VK_IME_ON | 0x16 | IME On |
| VK_JUNJA | 0x17 | IME Junja mode |
| VK_FINAL | 0x18 | IME final mode |
| VK_HANJA | 0x19 | IME Hanja mode |
| VK_KANJI | 0x19 | IME Kanji mode |
| VK_IME_OFF | 0x1A | IME Off |
| VK_ESCAPE | 0x1B | ESC key |
| VK_CONVERT | 0x1C | IME convert |
| VK_NONCONVERT | 0x1D | IME nonconvert |
| VK_ACCEPT | 0x1E | IME accept |
| VK_MODECHANGE | 0x1F | IME mode change request |
| VK_SPACE | 0x20 | SPACEBAR |
| VK_PRIOR | 0x21 | PAGE UP key |
| VK_NEXT | 0x22 | PAGE DOWN key |
| VK_END | 0x23 | END key |
| VK_HOME | 0x24 | HOME key |
| VK_LEFT | 0x25 | LEFT ARROW key |
| VK_UP | 0x26 | UP ARROW key |
| VK_RIGHT | 0x27 | RIGHT ARROW key |
| VK_DOWN | 0x28 | DOWN ARROW key |
| VK_SELECT | 0x29 | SELECT key |
| VK_PRINT | 0x2A | PRINT key |
| VK_EXECUTE | 0x2B | EXECUTE key |
| VK_SNAPSHOT | 0x2C | PRINT SCREEN key |
| VK_INSERT | 0x2D | INS key |
| VK_DELETE | 0x2E | DEL key |
| VK_HELP | 0x2F | HELP key |
| 0x30 | 0 key | |
| 0x31 | 1 key | |
| 0x32 | 2 key | |
| 0x33 | 3 key | |
| 0x34 | 4 key | |
| 0x35 | 5 key | |
| 0x36 | 6 key | |
| 0x37 | 7 key | |
| 0x38 | 8 key | |
| 0x39 | 9 key | |
| - | 0x3A-40 | Undefined |
| 0x41 | A key | |
| 0x42 | B key | |
| 0x43 | C key | |
| 0x44 | D key | |
| 0x45 | E key | |
| 0x46 | F key | |
| 0x47 | G key | |
| 0x48 | H key | |
| 0x49 | I key | |
| 0x4A | J key | |
| 0x4B | K key | |
| 0x4C | L key | |
| 0x4D | M key | |
| 0x4E | N key | |
| 0x4F | O key | |
| 0x50 | P key | |
| 0x51 | Q key | |
| 0x52 | R key | |
| 0x53 | S key | |
| 0x54 | T key | |
| 0x55 | U key | |
| 0x56 | V key | |
| 0x57 | W key | |
| 0x58 | X key | |
| 0x59 | Y key | |
| 0x5A | Z key | |
| VK_LWIN | 0x5B | Left Windows key |
| VK_RWIN | 0x5C | Right Windows key |
| VK_APPS | 0x5D | Applications key |
| - | 0x5E | Reserved |
| VK_SLEEP | 0x5F | Computer Sleep key |
| VK_NUMPAD0 | 0x60 | Numeric keypad 0 key |
| VK_NUMPAD1 | 0x61 | Numeric keypad 1 key |
| VK_NUMPAD2 | 0x62 | Numeric keypad 2 key |
| VK_NUMPAD3 | 0x63 | Numeric keypad 3 key |
| VK_NUMPAD4 | 0x64 | Numeric keypad 4 key |
| VK_NUMPAD5 | 0x65 | Numeric keypad 5 key |
| VK_NUMPAD6 | 0x66 | Numeric keypad 6 key |
| VK_NUMPAD7 | 0x67 | Numeric keypad 7 key |
| VK_NUMPAD8 | 0x68 | Numeric keypad 8 key |
| VK_NUMPAD9 | 0x69 | Numeric keypad 9 key |
| VK_MULTIPLY | 0x6A | Multiply key |
| VK_ADD | 0x6B | Add key |
| VK_SEPARATOR | 0x6C | Separator key |
| VK_SUBTRACT | 0x6D | Subtract key |
| VK_DECIMAL | 0x6E | Decimal key |
| VK_DIVIDE | 0x6F | Divide key |
| VK_F1 | 0x70 | F1 key |
| VK_F2 | 0x71 | F2 key |
| VK_F3 | 0x72 | F3 key |
| VK_F4 | 0x73 | F4 key |
| VK_F5 | 0x74 | F5 key |
| VK_F6 | 0x75 | F6 key |
| VK_F7 | 0x76 | F7 key |
| VK_F8 | 0x77 | F8 key |
| VK_F9 | 0x78 | F9 key |
| VK_F10 | 0x79 | F10 key |
| VK_F11 | 0x7A | F11 key |
| VK_F12 | 0x7B | F12 key |
| VK_F13 | 0x7C | F13 key |
| VK_F14 | 0x7D | F14 key |
| VK_F15 | 0x7E | F15 key |
| VK_F16 | 0x7F | F16 key |
| VK_F17 | 0x80 | F17 key |
| VK_F18 | 0x81 | F18 key |
| VK_F19 | 0x82 | F19 key |
| VK_F20 | 0x83 | F20 key |
| VK_F21 | 0x84 | F21 key |
| VK_F22 | 0x85 | F22 key |
| VK_F23 | 0x86 | F23 key |
| VK_F24 | 0x87 | F24 key |
| - | 0x88-8F | Reserved |
| VK_NUMLOCK | 0x90 | NUM LOCK key |
| VK_SCROLL | 0x91 | SCROLL LOCK key |
| - | 0x92-96 | OEM specific |
| - | 0x97-9F | Unassigned |
| VK_LSHIFT | 0xA0 | Left SHIFT key |
| VK_RSHIFT | 0xA1 | Right SHIFT key |
| VK_LCONTROL | 0xA2 | Left CONTROL key |
| VK_RCONTROL | 0xA3 | Right CONTROL key |
| VK_LMENU | 0xA4 | Left ALT key |
| VK_RMENU | 0xA5 | Right ALT key |
| VK_BROWSER_BACK | 0xA6 | Browser Back key |
| VK_BROWSER_FORWARD | 0xA7 | Browser Forward key |
| VK_BROWSER_REFRESH | 0xA8 | Browser Refresh key |
| VK_BROWSER_STOP | 0xA9 | Browser Stop key |
| VK_BROWSER_SEARCH | 0xAA | Browser Search key |
| VK_BROWSER_FAVORITES | 0xAB | Browser Favorites key |
| VK_BROWSER_HOME | 0xAC | Browser Start and Home key |
| VK_VOLUME_MUTE | 0xAD | Volume Mute key |
| VK_VOLUME_DOWN | 0xAE | Volume Down key |
| VK_VOLUME_UP | 0xAF | Volume Up key |
| VK_MEDIA_NEXT_TRACK | 0xB0 | Next Track key |
| VK_MEDIA_PREV_TRACK | 0xB1 | Previous Track key |
| VK_MEDIA_STOP | 0xB2 | Stop Media key |
| VK_MEDIA_PLAY_PAUSE | 0xB3 | Play/Pause Media key |
| VK_LAUNCH_MAIL | 0xB4 | Start Mail key |
| VK_LAUNCH_MEDIA_SELECT | 0xB5 | Select Media key |
| VK_LAUNCH_APP1 | 0xB6 | Start Application 1 key |
| VK_LAUNCH_APP2 | 0xB7 | Start Application 2 key |
| - | 0xB8-B9 | Reserved |
| VK_OEM_1 | 0xBA | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ;: key |
| VK_OEM_PLUS | 0xBB | For any country/region, the + key |
| VK_OEM_COMMA | 0xBC | For any country/region, the , key |
| VK_OEM_MINUS | 0xBD | For any country/region, the - key |
| VK_OEM_PERIOD | 0xBE | For any country/region, the . key |
| VK_OEM_2 | 0xBF | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the /? key |
| VK_OEM_3 | 0xC0 | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `~ key |
| - | 0xC1-DA | Reserved |
| VK_OEM_4 | 0xDB | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the [{ key |
| VK_OEM_5 | 0xDC | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \| key |
| VK_OEM_6 | 0xDD | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ]} key |
| VK_OEM_7 | 0xDE | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '" key |
| VK_OEM_8 | 0xDF | Used for miscellaneous characters; it can vary by keyboard. |
| - | 0xE0 | Reserved |
| - | 0xE1 | OEM specific |
| VK_OEM_102 | 0xE2 | The <> keys on the US standard keyboard, or the \| key on the non-US 102-key keyboard |
| - | 0xE3-E4 | OEM specific |
| VK_PROCESSKEY | 0xE5 | IME PROCESS key |
| - | 0xE6 | OEM specific |
| VK_PACKET | 0xE7 | Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP |
| - | 0xE8 | Unassigned |
| - | 0xE9-F5 | OEM specific |
| VK_ATTN | 0xF6 | Attn key |
| VK_CRSEL | 0xF7 | CrSel key |
| VK_EXSEL | 0xF8 | ExSel key |
| VK_EREOF | 0xF9 | Erase EOF key |
| VK_PLAY | 0xFA | Play key |
| VK_ZOOM | 0xFB | Zoom key |
| VK_NONAME | 0xFC | Reserved |
| VK_PA1 | 0xFD | PA1 key |
| VK_OEM_CLEAR | 0xFE | Clear key |