Module winInputHook
[hide private]
[frames] | no frames]

Source Code for Module winInputHook

  1  #winInputHook.py 
  2  #A part of NonVisual Desktop Access (NVDA) 
  3  #Copyright (C) 2006-2008 NVDA Contributors <http://www.nvda-project.org/> 
  4  #This file is covered by the GNU General Public License. 
  5  #See the file COPYING for more details. 
  6   
  7  import threading 
  8  import comtypes.client 
  9  import time 
 10  from ctypes import * 
 11  from ctypes.wintypes import * 
 12  from win32con import WM_QUIT, HC_ACTION, WH_KEYBOARD_LL, LLKHF_UP, LLKHF_EXTENDED, LLKHF_INJECTED, WH_MOUSE_LL, LLMHF_INJECTED 
13 14 -class KBDLLHOOKSTRUCT(Structure):
15 _fields_=[ 16 ('vkCode',DWORD), 17 ('scanCode',DWORD), 18 ('flags',DWORD), 19 ('time',DWORD), 20 ('dwExtraInfo',DWORD), 21 ]
22
23 -class MSLLHOOKSTRUCT(Structure):
24 _fields_=[ 25 ('pt',POINT), 26 ('mouseData',DWORD), 27 ('flags',DWORD), 28 ('time',DWORD), 29 ('dwExtraInfo',DWORD), 30 ]
31 32 keyDownCallback=None 33 keyUpCallback=None 34 mouseCallback=None
35 36 @WINFUNCTYPE(c_long,c_int,WPARAM,LPARAM) 37 -def keyboardHook(code,wParam,lParam):
38 if code!=HC_ACTION: 39 return windll.user32.CallNextHookEx(0,code,wParam,lParam) 40 kbd=KBDLLHOOKSTRUCT.from_address(lParam) 41 if keyUpCallback and kbd.flags&LLKHF_UP: 42 if not keyUpCallback(kbd.vkCode,kbd.scanCode,bool(kbd.flags&LLKHF_EXTENDED),bool(kbd.flags&LLKHF_INJECTED)): 43 return 1 44 elif keyDownCallback: 45 if not keyDownCallback(kbd.vkCode,kbd.scanCode,bool(kbd.flags&LLKHF_EXTENDED),bool(kbd.flags&LLKHF_INJECTED)): 46 return 1 47 return windll.user32.CallNextHookEx(0,code,wParam,lParam)
48
49 @WINFUNCTYPE(c_long,c_int,WPARAM,LPARAM) 50 -def mouseHook(code,wParam,lParam):
51 if code!=HC_ACTION: 52 return windll.user32.CallNextHookEx(0,code,wParam,lParam) 53 msll=MSLLHOOKSTRUCT.from_address(lParam) 54 if mouseCallback: 55 if not mouseCallback(wParam,msll.pt.x,msll.pt.y,msll.flags&LLMHF_INJECTED): 56 return 1 57 return windll.user32.CallNextHookEx(0,code,wParam,lParam)
58 59 hookThread=None 60 hookThreadRefCount=0
61 62 -def hookThreadFunc():
63 keyHookID=windll.user32.SetWindowsHookExW(WH_KEYBOARD_LL,keyboardHook,windll.kernel32.GetModuleHandleW(None),0) 64 if keyHookID==0: 65 raise OSError("Could not register keyboard hook") 66 mouseHookID=windll.user32.SetWindowsHookExW(WH_MOUSE_LL,mouseHook,windll.kernel32.GetModuleHandleW(None),0) 67 if mouseHookID==0: 68 raise OSError("Could not register mouse hook") 69 msg=MSG() 70 while windll.user32.GetMessageW(byref(msg),None,0,0): 71 pass 72 if windll.user32.UnhookWindowsHookEx(keyHookID)==0: 73 raise OSError("could not unregister key hook %s"%keyHookID) 74 if windll.user32.UnhookWindowsHookEx(mouseHookID)==0: 75 raise OSError("could not unregister mouse hook %s"%mouseHookID)
76
77 -def initialize():
78 global hookThread, hookThreadRefCount 79 hookThreadRefCount+=1 80 if hookThreadRefCount==1: 81 hookThread=threading.Thread(target=hookThreadFunc) 82 hookThread.start()
83
84 -def setCallbacks(keyUp=None,keyDown=None,mouse=None):
85 global keyUpCallback, keyDownCallback, mouseCallback 86 if keyUp: 87 keyUpCallback=keyUp 88 if keyDown: 89 keyDownCallback=keyDown 90 if mouse: 91 mouseCallback=mouse
92
93 -def terminate():
94 global hookThread, hookThreadRefCount 95 if not hookThread: 96 raise RuntimeError("winInputHook not running") 97 hookThreadRefCount-=1 98 if hookThreadRefCount==0: 99 windll.user32.PostThreadMessageW(hookThread.ident,WM_QUIT,0,0) 100 hookThread.join() 101 hookThread=None
102