pythonwindowspyhook

How to capture Shift + PrintScreen with pyHook?


I was trying to capture Shift+PrintScreen as Ctrl+c was captured in this answer.

Although the answer is outdated, but even if I fix the import, it doesn't works:

import pythoncom
from pyHook import HookManager, GetKeyState, HookConstants

def OnKeyboardEvent(event):
    ctrl_pressed = GetKeyState(HookConstants.VKeyToID('VK_CONTROL') >> 15)
    if ctrl_pressed and HookConstant.IDToName(event.keyId) == 'd':
        print("ctrl plus d was pressed at same time")

    return True

# create a hook manager
hm = HookManager()
# watch for all keyboard events
hm.KeyDown = OnKeyboardEvent
# set the hook
hm.HookKeyboard()
# wait forever
pythoncom.PumpMessages()

I wanted to capture PrintScreen key and open my Screenshot application, which I was able to do. Now I want to capture Shift + PrintScreen and open my application with some other config. How can I capture both key at once?


Solution

  • pyhook source code::HookManager.py lists all defined key constants. In your case you'll have to check for the Keystate VK_LSHIFT in combination with the event.KeyID VK_SNAPSHOT (PrintScrn Key). Here's a working example:

    import pythoncom
    from pyHook import HookManager, GetKeyState, HookConstants
    
    def OnKeyboardEvent(event):
        # in case you want to debug: uncomment next line
        # print repr(event), event.KeyID, HookConstants.IDToName(event.KeyID), event.ScanCode , event.Ascii, event.flags
        if GetKeyState(HookConstants.VKeyToID('VK_LSHIFT')) and event.KeyID == HookConstants.VKeyToID('VK_SNAPSHOT'):
            print("shift + snapshot pressed")
        elif GetKeyState(HookConstants.VKeyToID('VK_CONTROL')) and HookConstants.IDToName(event.KeyID) == 'D':
            print("ctrl + d pressed")
        return True
    
    # create a hook manager
    hm = HookManager()
    # watch for all mouse events
    hm.KeyDown = OnKeyboardEvent
    # set the hook
    hm.HookKeyboard()
    # wait forever
    pythoncom.PumpMessages()
    

    If you want to also bind it to the right-shift-key you'll have to check for the VK_RSHIFT keystate.

    if (GetKeyState(HookConstants.VKeyToID('VK_LSHIFT')) or GetKeyState(HookConstants.VKeyToID('VK_RSHIFT'))) and event.KeyID == HookConstants.VKeyToID('VK_SNAPSHOT'):