繁体   English   中英

使用 Python 自动检测键盘的焦点并从剪贴板粘贴

[英]Detect keyboard's focus and paste from clipboard, automatically using Python

我正在使用 Python 并尝试将已复制的文本从剪贴板自动粘贴到活动文本框或任何具有键盘焦点的内容。 换句话说,一旦我点击浏览器的地址栏或任何文本编辑器或任何文本框,程序应该自动粘贴从剪贴板复制的数据。

这在python中可能吗? 有什么功能吗? 我在网站上搜索过,但没有找到任何好的解决方案。

如果可能的话,一个小演示将不胜感激。

谢谢你。

您可以使用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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM