我正在制作一个自定义粘贴脚本,需要阻止操作系统在 ctrl+v 上粘贴,以便我可以用我自己的行为替换它。
这是一些测试代码,本应阻止操作系统粘贴,但事实并非如此:
import keyboard
block_os_paste = False # Flag to toggle blocking
print("Unblocked OS Ctrl+V. Default behavior.")
def toggle_blocking():
"""Toggle the blocking of OS Ctrl+V."""
global block_os_paste
block_os_paste = not block_os_paste
if block_os_paste:
print("Blocking OS Ctrl+V. Custom behavior enabled.")
else:
print("Unblocking OS Ctrl+V. Default behavior restored.")
def handle_ctrl_v(e):
"""Custom handler for Ctrl+V."""
if block_os_paste:
e.suppress = True
print("cookies") # Custom behavior
else:
keyboard.send("ctrl+v") # Send the default behavior
keyboard.add_hotkey("f9", toggle_blocking) # Assign hotkey to toggle blocking
keyboard.add_hotkey("ctrl+v", lambda: handle_ctrl_v(False)) # Intercept Ctrl+V
keyboard.wait("esc") # Exit the script when "Esc" is pressed
我也尝试过许多其他方法,例如使用 pynput 中的全局键盘侦听器,但我想出的方法都不起作用。任何帮助将不胜感激。
对于其他研究这个问题的人,我找到了解决方案。不幸的是,它非常有帮助,因此在其中实现我自己的功能并对其进行自定义将是可怕的。但有可能。
import ctypes
import ctypes.wintypes
import keyboard
import win32api
import win32con
# Define virtual key codes if not available in win32con
VK_V = 0x56 # Virtual key code for 'V'
VK_ESCAPE = 0x1B # Virtual key code for 'Esc'
# Variable to toggle blocking
block_os_paste = False
hHook = None # Initialize hHook as a global variable
def toggle_blocking():
"""Toggle the blocking of OS Ctrl+V."""
global block_os_paste
block_os_paste = not block_os_paste
if block_os_paste:
print("Blocking OS Ctrl+V")
else:
print("Unblocking OS Ctrl+V")
# Hook callback prototype
def low_level_keyboard_handler(nCode, wParam, lParam):
"""Low-level keyboard hook handler."""
if nCode == 0: # If wParam is WM_KEYDOWN or WM_KEYUP
# Extract virtual key code from lParam
key_info = ctypes.cast(lParam, ctypes.POINTER(ctypes.c_long)).contents
vk_code = key_info.value # Extract the virtual key code
isCtrlPressed = win32api.GetAsyncKeyState(win32con.VK_CONTROL) < 0
# Check for only WM_KEYDOWN
if wParam == win32con.WM_KEYDOWN:
if (vk_code == VK_V) and isCtrlPressed:
if block_os_paste:
print("Pasting has been blocked!") # Print only once
return 1 # Block the Ctrl+V event
# Check for Esc key press to exit
if vk_code == VK_ESCAPE:
print("Exiting...")
ctypes.windll.user32.PostQuitMessage(0) # Exit the message loop
return ctypes.windll.user32.CallNextHookEx(hHook, nCode, wParam, lParam)
# Set keyboard hook
def set_keyboard_hook():
"""Set a low-level keyboard hook."""
global hHook
WH_KEYBOARD_LL = 13
# Use ctypes.CFUNCTYPE to define the correct function pointer
LOW_LEVEL_KEYBOARD_HOOK = ctypes.WINFUNCTYPE(ctypes.c_long, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int))
low_level_handler = LOW_LEVEL_KEYBOARD_HOOK(low_level_keyboard_handler)
hHook = ctypes.windll.user32.SetWindowsHookExA(WH_KEYBOARD_LL, low_level_handler, None, 0)
msg = ctypes.wintypes.MSG()
while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), 0, 0, 0) != 0:
ctypes.windll.user32.TranslateMessage(ctypes.byref(msg))
ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg))
if __name__ == "__main__":
keyboard.add_hotkey('f9', toggle_blocking)
print("Press F9 to toggle blocking, Esc to exit.")
try:
set_keyboard_hook() # Set the keyboard hook
except KeyboardInterrupt:
pass
finally:
if hHook is not None:
ctypes.windll.user32.UnhookWindowsHookEx(hHook)
这将阻止粘贴并将其替换为打印在按下按键时打印的语句。可以改变它,以便它在按下键时执行某些操作,在按下键时执行其他操作。