因此,我试图弄清楚如何使用Python注册全局键盘挂钩。从我阅读的内容来看,在DLL中没有回调似乎是可以的。如果您使用WH_KEYBOARD_LL。我不能肯定会确认,但是我感到鼓舞的是我不会遇到1428错误,就像我试图说的那样WH_CBT
。
我得到了一个钩形手柄,但是按我的期望按键盘上的按钮时什么也没显示。
关于为什么不调用我的回调的任何想法?还是有可能吗?
相关代码:
import time
import string
import ctypes
import functools
import atexit
import pythoncom
from ctypes import windll
hookID = 0
class Keyboard(object):
KEY_EVENT_DOWN = 0
KEY_EVENT_UP = 2
KEY_ENTER = 2
KEY_SHIFT = 16
KEY_SPACE = 32
HOOK_ACTION = 13
HOOK_KEYBOARD = 13
HOOK_KEYDOWN = 0x100
HOOK_KEYUP = 0x101
class Hook:
'''Holds general hook information'''
def __init__(self):
self.hook = 0
self.struct = None
class HookStruct(ctypes.Structure):
'''Structure that windows returns for keyboard events'''
__fields__ = [
('keycode', ctypes.c_long),
('scancode', ctypes.c_long),
('flags', ctypes.c_long),
('time', ctypes.c_long),
('info', ctypes.POINTER(ctypes.c_ulong))
]
def ascii_to_keycode(self, char):
return windll.user32.VkKeyScanA(ord(char))
def inject_key_down(self, keycode):
scancode = windll.user32.MapVirtualKeyA(keycode, 0)
windll.user32.keybd_event(keycode, scancode, Keyboard.KEY_EVENT_DOWN, 0)
def inject_key_up(self, keycode):
scan = windll.user32.MapVirtualKeyA(keycode, 0)
windll.user32.keybd_event(keycode, scan, Keyboard.KEY_EVENT_UP, 0)
def inject_key_press(self, keycode, pause=0.05):
self.inject_key_down(keycode)
time.sleep(pause)
self.inject_key_up(keycode)
def inject_sequence(self, seq, pause=0.05):
for key in seq:
if key == ' ':
self.inject_key_press(Keyboard.KEY_SPACE, pause)
elif key == '\n':
self.inject_key_press(Keyboard.KEY_ENTER, pause)
else:
if key in string.ascii_uppercase:
self.inject_key_down(Keyboard.KEY_SHIFT)
self.inject_key_press(self.ascii_to_keycode(key), pause)
self.inject_key_up(Keyboard.KEY_SHIFT)
else:
self.inject_key_press(self.ascii_to_keycode(key), pause)
def _win32_copy_mem(self, dest, src):
src = ctypes.c_void_p(src)
windll.kernel32.RtlMoveMemory(ctypes.addressof(dest), src, ctypes.sizeof(dest))
def _win32_get_last_error(self):
return windll.kernel32.GetLastError()
def _win32_get_module(self, mname):
return windll.kernel32.GetModuleHandleA(mname)
def _win32_call_next_hook(self, id, code, wparam, lparam):
return windll.kernel32.CallNextHookEx(id, code, wparam, lparam)
def _win32_set_hook(self, id, callback, module, thread):
callback_decl = ctypes.WINFUNCTYPE(ctypes.c_long, ctypes.c_long, ctypes.c_long, ctypes.c_long)
return windll.user32.SetWindowsHookExA(id, callback_decl(callback), module, thread)
def _win32_unhook(self, id):
return windll.user32.UnhookWindowsHookEx(id)
def keyboard_event(self, data):
print data.scancode
return False
def capture_input(self):
self.hook = Keyboard.Hook()
self.hook.struct = Keyboard.HookStruct()
def low_level_keyboard_proc(code, event_type, kb_data_ptr):
# win32 spec says return result of CallNextHookEx if code is less than 0
if code < 0:
return self._win32_call_next_hook(self.hook.hook, code, event_type, kb_data_ptr)
if code == Keyboard.HOOK_ACTION:
# copy data from struct into Python structure
self._win32_copy_mem(self.hook.struct, kb_data_ptr)
# only call other handlers if we return false from our handler - allows to stop processing of keys
if self.keyboard_event(self.hook.struct):
return self._win32_call_next_hook(self.hook.hook, code, event_type, kb_data_ptr)
# register hook
try:
hookId = self.hook.hook = self._win32_set_hook(Keyboard.HOOK_KEYBOARD, low_level_keyboard_proc, self._win32_get_module(0), 0)
if self.hook.hook == 0:
print 'Error - ', self._win32_get_last_error()
else:
print 'Hook ID - ', self.hook.hook
except Exception, error:
print error
# unregister hook if python exits
atexit.register(functools.partial(self._win32_unhook, self.hook.hook))
def end_capture(self):
if self.hook.hook:
return self._win32_unhook(self.hook.hook)
kb = Keyboard()#kb.inject_sequence('This is a test\nand tHis is line 2')
kb.capture_input()
pythoncom.PumpMessages()
kb.end_capture()
我无法让您的课程上课,但我在此线程中找到了一种实现相同目标的类似方法。
这是改编后的代码:
from collections import namedtuple
KeyboardEvent = namedtuple('KeyboardEvent', ['event_type', 'key_code',
'scan_code', 'alt_pressed',
'time'])
handlers = []
def listen():
"""
Calls `handlers` for each keyboard event received. This is a blocking call.
"""
# Adapted from http://www.hackerthreads.org/Topic-42395
from ctypes import windll, CFUNCTYPE, POINTER, c_int, c_void_p, byref
import win32con, win32api, win32gui, atexit
event_types = {win32con.WM_KEYDOWN: 'key down',
win32con.WM_KEYUP: 'key up',
0x104: 'key down', # WM_SYSKEYDOWN, used for Alt key.
0x105: 'key up', # WM_SYSKEYUP, used for Alt key.
}
def low_level_handler(nCode, wParam, lParam):
"""
Processes a low level Windows keyboard event.
"""
event = KeyboardEvent(event_types[wParam], lParam[0], lParam[1],
lParam[2] == 32, lParam[3])
for handler in handlers:
handler(event)
# Be a good neighbor and call the next hook.
return windll.user32.CallNextHookEx(hook_id, nCode, wParam, lParam)
# Our low level handler signature.
CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
# Convert the Python handler into C pointer.
pointer = CMPFUNC(low_level_handler)
# Hook both key up and key down events for common keys (non-system).
hook_id = windll.user32.SetWindowsHookExA(win32con.WH_KEYBOARD_LL, pointer,
win32api.GetModuleHandle(None), 0)
# Register to remove the hook when the interpreter exits. Unfortunately a
# try/finally block doesn't seem to work here.
atexit.register(windll.user32.UnhookWindowsHookEx, hook_id)
while True:
msg = win32gui.GetMessage(None, 0, 0)
win32gui.TranslateMessage(byref(msg))
win32gui.DispatchMessage(byref(msg))
if __name__ == '__main__':
def print_event(e):
print(e)
handlers.append(print_event)
listen()
我制作了一个高级库来包装:keyboard
。
键盘移动 只需再做一点微小的工作,你就可以建立一个通过鼠标控制精灵移动的简单系统。为了简化你的代码,我建议你用一个名为keyboard的自定义函数来监听和捕捉键盘事件。 function keyboard(keyCode) { let key = {}; key.code = keyCode; key.isDown = false; key.isUp = true; key.p
所以我手头有一个非常奇怪的问题,数小时的搜索没有提供任何信息。 我有一个包含uitextfield的uiview。现在,该视图最初位于可见屏幕之外,坐标为x=-500,y=-500。 然而,在响应按钮按下此视图动画和移动到屏幕的中心。 现在,每当我点击作为此视图子视图的uitextfield时。此视图会在屏幕外移动回其原始坐标。 我已经疯狂地检查了我的代码,一旦它进入,就没有任何东西会再次将视图移
我有一个带有多个面板的JFrame类,我通过使用paintComponent(graphics g)方法绘制所有的图形,因此使用CardLayout没有任何用处。要切换帧,我只需点击一个按钮,比如回车,但问题是,当我切换面板时,paintCompenent中剩下的图形仍然存在。我还尝试使用panel.setvisible(false)使面板可见,这有点帮助,只是我要转换到的面板仍然不可见,即使在将
本文向大家介绍javascript 通过键名获取键盘的keyCode方法,包括了javascript 通过键名获取键盘的keyCode方法的使用技巧和注意事项,需要的朋友参考一下 不废话,直接看代码,需要的根据需求完善。 例:getKeyCode('a') 返回:65 以上这篇javascript 通过键名获取键盘的keyCode方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家
问题内容: 如何在Python中控制鼠标和键盘? 这个想法与Java中的Robot()类相同。可以说:将鼠标从此处移至此处,单击此处,然后将其写在屏幕上。 对于Windows,有win32api,但我主要使用Linux。 对于Linux,有Xlib,但它也适用于键盘吗?(仅找到对鼠标的引用) 有跨平台的解决方案吗?(Linux,Windows甚至OS X都很棒。) 问题答案: 对于鼠标,我发现py
问题内容: 我正在尝试使用Actions.sendKeys发送快捷方式,但是它不起作用。 问题答案: 您可以检查有关此问题的信息- 按下(Ctrl + A)SeleniumWebDriver 检查使用 和弦方法 的答案,您可以执行以下操作-