Вы можете использовать SendInput
для захвата фокуса текущего окна и ввода символов. Вот реализация, которая должна работать для ваших целей. Он берет содержимое буфера обмена и печатает его, если объект в фокусе собирает такой ввод с клавиатуры.
import time
import string
import ctypes
import ctypes.wintypes
# part one: clipboard text retrieval
CF_UNICODETEXT = 13 # unicode text format; terminates with a linefeed
OpenClipboard = ctypes.windll.user32.OpenClipboard
OpenClipboard.argtypes = ctypes.wintypes.HWND,
OpenClipboard.restype = ctypes.wintypes.BOOL
GetClipboardData = ctypes.windll.user32.GetClipboardData
GetClipboardData.argtypes = ctypes.wintypes.UINT,
GetClipboardData.restype = ctypes.wintypes.HANDLE
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalLock.argtypes = ctypes.wintypes.HGLOBAL,
GlobalLock.restype = ctypes.wintypes.LPVOID
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GlobalUnlock.argtypes = ctypes.wintypes.HGLOBAL,
GlobalUnlock.restype = ctypes.wintypes.BOOL
CloseClipboard = ctypes.windll.user32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = ctypes.wintypes.BOOL
def get_clipboard_text():
text = ""
if OpenClipboard(None):
h_clip_mem = GetClipboardData(CF_UNICODETEXT)
text = ctypes.wstring_at(GlobalLock(h_clip_mem))
GlobalUnlock(h_clip_mem)
CloseClipboard()
return text
CB_TEXT = get_clipboard_text()
# part two: typing it into the focused element of a window
LONG = ctypes.c_long
DWORD = ctypes.c_ulong
ULONG_PTR = ctypes.POINTER(DWORD)
WORD = ctypes.c_ushort
VK_SHIFT = 0x10 # Shift key
# special keys
VK_OEM_1 = 0xBA
VK_OEM_PLUS = 0xBB
VK_OEM_COMMA = 0xBC
VK_OEM_MINUS = 0xBD
VK_OEM_PERIOD = 0xBE
VK_OEM_2 = 0xBF
VK_OEM_3 = 0xC0
VK_OEM_4 = 0xDB
VK_OEM_5 = 0xDC
VK_OEM_6 = 0xDD
VK_OEM_7 = 0xDE
KEYEVENTF_KEYUP = 0x0002 # Releases the key
INPUT_KEYBOARD = 1
UPPER = frozenset('~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?')
LOWER = frozenset("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./")
ORDER = string.ascii_letters + string.digits + ' \b\r\t'
ALTER = dict(zip('!@#$%^&*()', '1234567890'))
OTHER = {
'`': VK_OEM_3, '~': VK_OEM_3, '-': VK_OEM_MINUS, '_': VK_OEM_MINUS,
'=': VK_OEM_PLUS, '+': VK_OEM_PLUS, '[': VK_OEM_4, '{': VK_OEM_4,
']': VK_OEM_6, '}': VK_OEM_6, '\\': VK_OEM_5, '|': VK_OEM_5,
';': VK_OEM_1, ':': VK_OEM_1, "'": VK_OEM_7, '"': VK_OEM_7,
',': VK_OEM_COMMA, '<': VK_OEM_COMMA, '.': VK_OEM_PERIOD,
'>': VK_OEM_PERIOD, '/': VK_OEM_2, '?': VK_OEM_2
}
class KEYBDINPUT(ctypes.Structure):
_fields_ = (
('wVk', WORD),
('wScan', WORD),
('dwFlags', DWORD),
('time', DWORD),
('dwExtraInfo', ULONG_PTR)
)
class INPUT(ctypes.Structure):
_fields_ = ('type', DWORD), ('ki', KEYBDINPUT), ('pad', ctypes.c_ubyte * 8)
def Input(structure):
return INPUT(INPUT_KEYBOARD, structure)
def KeyboardInput(code, flags):
return KEYBDINPUT(code, code, flags, 0, None)
def Keyboard(code, flags=0):
return Input(KeyboardInput(code, flags))
def SendInput(*inputs):
nInputs = len(inputs)
LPINPUT = INPUT * nInputs
pInputs = LPINPUT(*inputs)
cbSize = ctypes.c_int(ctypes.sizeof(INPUT))
return ctypes.windll.user32.SendInput(nInputs, pInputs, cbSize)
def stream(string):
mode = False
for character in string.replace('\r\n', '\r').replace('\n', '\r'):
if mode and character in LOWER or not mode and character in UPPER:
yield Keyboard(VK_SHIFT, mode and KEYEVENTF_KEYUP)
mode = not mode
character = ALTER.get(character, character)
if character in ORDER:
code = ord(character.upper())
elif character in OTHER:
code = OTHER[character]
else:
continue
raise ValueError('Undecoded')
yield Keyboard(code)
yield Keyboard(code, KEYEVENTF_KEYUP)
if mode:
yield Keyboard(VK_SHIFT, KEYEVENTF_KEYUP)
def send_clipboard():
for k in stream(CB_TEXT + '\r'):
SendInput(k)
def demo(wait=3):
time.sleep(wait)
send_clipboard()
if __name__ == '__main__':
demo()