|
|
@ -1,29 +1,22 @@
|
|
|
|
from pynput import keyboard
|
|
|
|
from pynput import keyboard
|
|
|
|
|
|
|
|
import datetime # datetime functions
|
|
|
|
|
|
|
|
import time # time functions
|
|
|
|
# Init the keyboard listener
|
|
|
|
# Init the keyboard listener
|
|
|
|
def Init(inGSettings):
|
|
|
|
def Init(inGSettings):
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
def lang():
|
|
|
|
def lang(inKLID = None):
|
|
|
|
# https://stackoverflow.com/questions/42047253/how-to-detect-current-keyboard-language-in-python
|
|
|
|
# https://stackoverflow.com/questions/42047253/how-to-detect-current-keyboard-language-in-python
|
|
|
|
# My keyboard is set to the English - United States keyboard
|
|
|
|
# My keyboard is set to the English - United States keyboard
|
|
|
|
import ctypes
|
|
|
|
import ctypes
|
|
|
|
# For debugging Windows error codes in the current thread
|
|
|
|
# For debugging Windows error codes in the current thread
|
|
|
|
user32 = ctypes.WinDLL('user32', use_last_error=True)
|
|
|
|
user32 = ctypes.WinDLL('user32', use_last_error=True)
|
|
|
|
curr_window = user32.GetForegroundWindow()
|
|
|
|
|
|
|
|
thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
|
|
|
|
|
|
|
|
# Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID
|
|
|
|
|
|
|
|
klid = user32.GetKeyboardLayout(thread_id)
|
|
|
|
|
|
|
|
# Language ID -> low 10 bits, Sub-language ID -> high 6 bits
|
|
|
|
|
|
|
|
# Extract language ID from KLID
|
|
|
|
|
|
|
|
lid = klid & (2**16 - 1)
|
|
|
|
|
|
|
|
# Convert language ID from decimal to hexadecimal
|
|
|
|
|
|
|
|
lid_hex = hex(lid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# I switched my keyboard to the Russian keyboard
|
|
|
|
# I switched my keyboard to the Russian keyboard
|
|
|
|
curr_window = user32.GetForegroundWindow()
|
|
|
|
curr_window = user32.GetForegroundWindow()
|
|
|
|
thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
|
|
|
|
thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
|
|
|
|
klid = user32.GetKeyboardLayout(thread_id)
|
|
|
|
# Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID
|
|
|
|
|
|
|
|
klid = inKLID
|
|
|
|
|
|
|
|
if klid is None:
|
|
|
|
|
|
|
|
klid = user32.GetKeyboardLayout(thread_id) # English = 67699721, Russian = 68748313
|
|
|
|
#print("LANG:", klid)
|
|
|
|
#print("LANG:", klid)
|
|
|
|
# Extract language ID from KLID
|
|
|
|
# Extract language ID from KLID
|
|
|
|
lid = klid & (2**16 - 1)
|
|
|
|
lid = klid & (2**16 - 1)
|
|
|
@ -57,41 +50,84 @@ def ToUn(vk,sc,wfl,hkid):
|
|
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
|
|
# Technical defs
|
|
|
|
# Technical defs
|
|
|
|
import pdb
|
|
|
|
import pdb
|
|
|
|
|
|
|
|
SpecialKeyList = []
|
|
|
|
|
|
|
|
inList = [
|
|
|
|
|
|
|
|
# {
|
|
|
|
|
|
|
|
# "EventDatetime": datetime.datetime.now(),
|
|
|
|
|
|
|
|
# "EventTypeStr": "HOTKEY" # HOTKEY | CHARACTER | DELETE
|
|
|
|
|
|
|
|
# "ValueStr": "" # HOTKEY: alt_l+shift or ctrl_l+c
|
|
|
|
|
|
|
|
# }
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def on_press(key):
|
|
|
|
def on_press(key):
|
|
|
|
|
|
|
|
lResult = { "EventDatetime": datetime.datetime.now(), "EventTypeStr": "HOTKEY", "ValueStr": ""}
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
print('alphanumeric key {0} pressed'.format(
|
|
|
|
#print('alphanumeric key {0} pressed'.format(
|
|
|
|
key.char))
|
|
|
|
# key.char))
|
|
|
|
#print("__",dir(key))
|
|
|
|
#print("__",dir(key))
|
|
|
|
import win32api
|
|
|
|
import win32api
|
|
|
|
MAPVK_VK_TO_CHAR = 0
|
|
|
|
MAPVK_VK_TO_CHAR = 0
|
|
|
|
#scancode = win32api.MapVirtualKey(key.vk, MAPVK_VK_TO_CHAR)
|
|
|
|
#scancode = win32api.MapVirtualKey(key.vk, MAPVK_VK_TO_CHAR)
|
|
|
|
from ctypes import windll
|
|
|
|
from ctypes import windll
|
|
|
|
#result = windll.User32.MapVirtualKeyExA(key.vk,MAPVK_VK_TO_CHAR,windll.User32.GetKeyboardLayout(1))
|
|
|
|
#result = windll.User32.MapVirtualKeyExA(key.vk,MAPVK_VK_TO_CHAR,windll.User32.GetKeyboardLayout(1))
|
|
|
|
print("WINDOWS:",ToUn(key.vk, key._scan, 0, lang()))
|
|
|
|
lDestKey = ToUn(key.vk, key._scan, 0, lang())
|
|
|
|
|
|
|
|
if str(key).isupper():
|
|
|
|
#print("WINDOWS:",result)
|
|
|
|
lDestKey = lDestKey.upper()
|
|
|
|
|
|
|
|
#print("WINDOWS:",lDestKey)
|
|
|
|
|
|
|
|
# Add result in list
|
|
|
|
|
|
|
|
if len(SpecialKeyList) > 0 and not (len(SpecialKeyList)==1 and "shift" in SpecialKeyList):
|
|
|
|
|
|
|
|
lDestKey = ToUn(key.vk, key._scan, 0, 67699721) # English = 67699721
|
|
|
|
|
|
|
|
lResult["EventTypeStr"] = "HOTKEY"
|
|
|
|
|
|
|
|
lResult["ValueStr"] = '+'.join(SpecialKeyList)+f"+{lDestKey}"
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
lResult["EventTypeStr"] = "CHARACTER"
|
|
|
|
|
|
|
|
lResult["ValueStr"] = lDestKey
|
|
|
|
|
|
|
|
print(lResult)
|
|
|
|
|
|
|
|
inList.append(lResult)
|
|
|
|
except AttributeError:
|
|
|
|
except AttributeError:
|
|
|
|
print('special key {0} pressed'.format(
|
|
|
|
#print('special key {0} pressed'.format(
|
|
|
|
key))
|
|
|
|
# key))
|
|
|
|
return True
|
|
|
|
lKeyStr = str(key)[4:]
|
|
|
|
|
|
|
|
# Check if not the delete or backspace
|
|
|
|
|
|
|
|
if lKeyStr != "backspace" and lKeyStr != "delete":
|
|
|
|
|
|
|
|
SpecialKeyList.append(lKeyStr)
|
|
|
|
|
|
|
|
# Add result in list
|
|
|
|
|
|
|
|
if len(SpecialKeyList) >= 2 or (lKeyStr != "shift" and lKeyStr != "ctrl_l" and lKeyStr != "ctrl_r" and lKeyStr != "alt_l" and lKeyStr != "alt_r" and lKeyStr != "shift_r"):
|
|
|
|
|
|
|
|
lResult["EventTypeStr"] = "HOTKEY"
|
|
|
|
|
|
|
|
lResult["ValueStr"] = '+'.join(SpecialKeyList)
|
|
|
|
|
|
|
|
inList.append(lResult)
|
|
|
|
|
|
|
|
print(lResult)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
lResult["EventTypeStr"] = "DELETE"
|
|
|
|
|
|
|
|
lResult["ValueStr"] = ('+'.join(SpecialKeyList)+f"+{lKeyStr}" if len(SpecialKeyList)>0 else f"{lKeyStr}")
|
|
|
|
|
|
|
|
inList.append(lResult)
|
|
|
|
|
|
|
|
print(lResult)
|
|
|
|
|
|
|
|
#return True
|
|
|
|
|
|
|
|
|
|
|
|
def on_release(key):
|
|
|
|
def on_release(key):
|
|
|
|
print('{0} released'.format(
|
|
|
|
if len(SpecialKeyList)>0:
|
|
|
|
key))
|
|
|
|
try:
|
|
|
|
#pdb.set_trace()
|
|
|
|
SpecialKeyList.remove(str(key)[4:])
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
pass
|
|
|
|
if key == keyboard.Key.esc:
|
|
|
|
if key == keyboard.Key.esc:
|
|
|
|
# Stop listener
|
|
|
|
# Stop listener
|
|
|
|
return True
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
# Collect events until released
|
|
|
|
# Collect events until released
|
|
|
|
while True:
|
|
|
|
#while True:
|
|
|
|
with keyboard.Listener(
|
|
|
|
# with keyboard.Listener(
|
|
|
|
on_press=on_press,
|
|
|
|
# on_press=on_press,
|
|
|
|
on_release=on_release) as listener:
|
|
|
|
# on_release=on_release) as listener:
|
|
|
|
listener.join()
|
|
|
|
# listener.join()
|
|
|
|
|
|
|
|
|
|
|
|
# ...or, in a non-blocking fashion:
|
|
|
|
# ...or, in a non-blocking fashion:
|
|
|
|
listener = keyboard.Listener(
|
|
|
|
listener = keyboard.Listener(
|
|
|
|
on_press=on_press,
|
|
|
|
on_press=on_press,
|
|
|
|
on_release=on_release)
|
|
|
|
on_release=on_release)
|
|
|
|
listener.start()
|
|
|
|
listener.start()
|
|
|
|
|
|
|
|
import pprint
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
|
|
#print(inList)
|
|
|
|
|
|
|
|
#pprint.pprint(inList)
|