reckoner
reckoner

Reputation: 2981

Block pyhook from so-generated keystrokes?

I'm using pyhook and pyhk to map keystrokes on a windows XP machine, and it works fine except for when the keystroke (say, ctrl+z) already exists in the application. In that case, the ctrl+z passes to the application and triggers the action that has been mapped to it.

If you are familiar with autohotkey, note that autohotkey gets around this by defining hotkeys that can optionally be passed to the underlying application. Here's a bit of codes that gets at the idea. Note that I'm trying to keep track of when the ctrl key is down.

  import pythoncom, pyHook
  control_down = False

  def OnKeyboardEvent_up(event):
      global control_down
      if event.Key=='Lcontrol' or event.Key=='Rcontrol':
         control_down=False
      return True

  def OnKeyboardEvent(event,action=None,key='Z',context=None):
      global control_down
      if event.Key=='Lcontrol' or event.Key=='Rcontrol':
         control_down=True
      if control_down and event.Key==key:
         print 'do something'
         return False
      if event.Key=='Pause':
         win32gui.PostQuitMessage(1)
         return False
      # return True to pass the event to other handlers
      return True

  if __name__ == '__main__':
     hm = pyHook.HookManager()
     hm.KeyDown = OnKeyboardEvent
     hm.KeyUp = OnKeyboardEvent_up
     hm.HookKeyboard() # set the hook
     pythoncom.PumpMessages() # wait forever

Any help appreciated.

Thanks!

Upvotes: 4

Views: 1025

Answers (3)

Dede95
Dede95

Reputation: 41

In windows I noticed that if the code "Do something" takes too long than the key codes are passed to the application even if you return False in the OnKeyboardEvent handler. The solution for me was to pack the code in a thread launched by the key or key combination press. This is sufficiently fast to make the return False work as expected.

def OnKeyboardEvent(event):
      if event.key == myKey:
         myThred = threading.Thread(target=doSomething_Function).start()
         return False

Upvotes: 0

andrewmh20
andrewmh20

Reputation: 180

I may totally wrong here, but from my understanding of the pyHook documentation, in order to prevent the key presses from being sent to another application you need to change the return True in def OnKeyboardEvent_up(event): and OnKeyboardEvent(event,action=None,key='Z',context=None): to return False (or anything else other than True.

Upvotes: 0

Rostyslav Dzinko
Rostyslav Dzinko

Reputation: 40755

If you're insterested in Windows only, you can use win API, e.g. via ctypes:

>>> from ctypes import windll
>>> windll.user32.RegisterHotKey(0, -1, 0x0002, 0x5a)

After running these lines of code Ctrl (code = 0x0002) + Z (code = 0x5a) combination doesn't work any more in Python REPL.

So you should better look at what windows are those hotkey registered. More information you can find in MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309(v=vs.85).aspx

Upvotes: 3

Related Questions