You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.3 KiB
97 lines
3.3 KiB
4 years ago
|
from pynput import keyboard
|
||
|
|
||
|
|
||
|
# Init the keyboard listener
|
||
|
def Init(inGSettings):
|
||
|
pass
|
||
|
def lang():
|
||
|
# https://stackoverflow.com/questions/42047253/how-to-detect-current-keyboard-language-in-python
|
||
|
# My keyboard is set to the English - United States keyboard
|
||
|
import ctypes
|
||
|
# For debugging Windows error codes in the current thread
|
||
|
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
|
||
|
curr_window = user32.GetForegroundWindow()
|
||
|
thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
|
||
|
klid = user32.GetKeyboardLayout(thread_id)
|
||
|
#print("LANG:", klid)
|
||
|
# Extract language ID from KLID
|
||
|
lid = klid & (2**16 - 1)
|
||
|
# Convert language ID from decimal to hexadecimal
|
||
|
lid_hex = hex(lid)
|
||
|
#print("LANG:",lid)
|
||
|
return klid
|
||
|
|
||
|
# https://stackoverflow.com/questions/38224277/tounicodeex-always-returns-0-in-python
|
||
|
from ctypes import *
|
||
|
_ToUnicodeEx = WinDLL('user32').ToUnicodeEx
|
||
|
_ToUnicodeEx.argtypes = [c_uint,c_uint,POINTER(c_char),POINTER(c_wchar),c_int,c_uint,c_void_p]
|
||
|
_ToUnicodeEx.restype = c_int
|
||
|
def ToUn(vk,sc,wfl,hkid):
|
||
|
kst = create_string_buffer(256)
|
||
|
b = create_unicode_buffer(5)
|
||
|
windll.User32.GetKeyboardState(kst)
|
||
|
y= _ToUnicodeEx(vk,sc,kst,b,5,wfl,hkid)
|
||
|
VK_SHIFT = 0x10
|
||
|
VK_CAPITAL = 0x14
|
||
|
shifted = False
|
||
|
# TODO UPPER CASE https://stackoverflow.com/questions/42037204/why-getkeystate-changed-the-behavior-of-tounicodeex
|
||
|
if windll.User32.GetKeyboardState(VK_SHIFT) < 0:
|
||
|
shifted = True
|
||
|
if windll.User32.GetKeyboardState(VK_CAPITAL) < 0:
|
||
|
shifted = True
|
||
|
if shifted:
|
||
|
return b.value.upper()
|
||
|
return b.value
|
||
|
#print(ToUn(65,0,0,windll.User32.GetKeyboardLayout(1)))
|
||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||
|
# Technical defs
|
||
|
import pdb
|
||
|
def on_press(key):
|
||
|
try:
|
||
|
print('alphanumeric key {0} pressed'.format(
|
||
|
key.char))
|
||
|
#print("__",dir(key))
|
||
|
import win32api
|
||
|
MAPVK_VK_TO_CHAR = 0
|
||
|
#scancode = win32api.MapVirtualKey(key.vk, MAPVK_VK_TO_CHAR)
|
||
|
from ctypes import windll
|
||
|
#result = windll.User32.MapVirtualKeyExA(key.vk,MAPVK_VK_TO_CHAR,windll.User32.GetKeyboardLayout(1))
|
||
|
print("WINDOWS:",ToUn(key.vk, key._scan, 0, lang()))
|
||
|
|
||
|
#print("WINDOWS:",result)
|
||
|
except AttributeError:
|
||
|
print('special key {0} pressed'.format(
|
||
|
key))
|
||
|
return True
|
||
|
|
||
|
def on_release(key):
|
||
|
print('{0} released'.format(
|
||
|
key))
|
||
|
#pdb.set_trace()
|
||
|
if key == keyboard.Key.esc:
|
||
|
# Stop listener
|
||
|
return True
|
||
|
|
||
|
# Collect events until released
|
||
|
while True:
|
||
|
with keyboard.Listener(
|
||
|
on_press=on_press,
|
||
|
on_release=on_release) as listener:
|
||
|
listener.join()
|
||
|
|
||
|
# ...or, in a non-blocking fashion:
|
||
|
listener = keyboard.Listener(
|
||
|
on_press=on_press,
|
||
|
on_release=on_release)
|
||
|
listener.start()
|