openmedialibrary_platform_w.../Lib/site-packages/pythonwin/pywin/scintilla/keycodes.py
2016-04-14 21:54:42 +02:00

177 lines
5.1 KiB
Python

import string
import win32con
import win32api
import win32ui
MAPVK_VK_TO_CHAR = 2
key_name_to_vk = {}
key_code_to_name = {}
_better_names = {
"escape": "esc",
"return": "enter",
"back": "pgup",
"next": "pgdn",
}
def _fillvkmap():
# Pull the VK_names from win32con
names = [entry for entry in win32con.__dict__ if entry.startswith("VK_")]
for name in names:
code = getattr(win32con, name)
n = name[3:].lower()
key_name_to_vk[n] = code
if n in _better_names:
n = _better_names[n]
key_name_to_vk[n] = code
key_code_to_name[code] = n
_fillvkmap()
def get_vk(chardesc):
if len(chardesc)==1:
# it is a character.
info = win32api.VkKeyScan(chardesc)
if info==-1:
return None, None
vk = win32api.LOBYTE(info)
state = win32api.HIBYTE(info)
modifiers = 0
if state & 0x1:
modifiers |= win32con.SHIFT_PRESSED
if state & 0x2:
modifiers |= win32con.LEFT_CTRL_PRESSED | win32con.RIGHT_CTRL_PRESSED
if state & 0x4:
modifiers |= win32con.LEFT_ALT_PRESSED | win32con.RIGHT_ALT_PRESSED
return vk, modifiers
# must be a 'key name'
return key_name_to_vk.get(chardesc.lower()), 0
modifiers = {
"alt" : win32con.LEFT_ALT_PRESSED | win32con.RIGHT_ALT_PRESSED,
"lalt" : win32con.LEFT_ALT_PRESSED,
"ralt" : win32con.RIGHT_ALT_PRESSED,
"ctrl" : win32con.LEFT_CTRL_PRESSED | win32con.RIGHT_CTRL_PRESSED,
"ctl" : win32con.LEFT_CTRL_PRESSED | win32con.RIGHT_CTRL_PRESSED,
"control" : win32con.LEFT_CTRL_PRESSED | win32con.RIGHT_CTRL_PRESSED,
"lctrl" : win32con.LEFT_CTRL_PRESSED,
"lctl" : win32con.LEFT_CTRL_PRESSED,
"rctrl" : win32con.RIGHT_CTRL_PRESSED,
"rctl" : win32con.RIGHT_CTRL_PRESSED,
"shift" : win32con.SHIFT_PRESSED,
"key" : 0, # ignore key tag.
}
def parse_key_name(name):
name = name + "-" # Add a sentinal
start = pos = 0
max = len(name)
toks = []
while pos<max:
if name[pos] in "+-":
tok = name[start:pos]
# use the ascii lower() version of tok, so ascii chars require
# an explicit shift modifier - ie 'Ctrl+G' should be treated as
# 'ctrl+g' - 'ctrl+shift+g' would be needed if desired.
# This is mainly to avoid changing all the old keystroke defs
toks.append(tok.lower())
pos += 1 # skip the sep
start = pos
pos += 1
flags = 0
# do the modifiers
for tok in toks[:-1]:
mod = modifiers.get(tok.lower())
if mod is not None:
flags |= mod
# the key name
vk, this_flags = get_vk(toks[-1])
return vk, flags | this_flags
_checks = [
[ # Shift
("Shift", win32con.SHIFT_PRESSED),
],
[ # Ctrl key
("Ctrl", win32con.LEFT_CTRL_PRESSED | win32con.RIGHT_CTRL_PRESSED),
("LCtrl", win32con.LEFT_CTRL_PRESSED),
("RCtrl", win32con.RIGHT_CTRL_PRESSED),
],
[ # Alt key
("Alt", win32con.LEFT_ALT_PRESSED | win32con.RIGHT_ALT_PRESSED),
("LAlt", win32con.LEFT_ALT_PRESSED),
("RAlt", win32con.RIGHT_ALT_PRESSED),
],
]
def make_key_name(vk, flags):
# Check alt keys.
flags_done = 0
parts = []
for moddata in _checks:
for name, checkflag in moddata:
if flags & checkflag:
parts.append(name)
flags_done = flags_done & checkflag
break
if flags_done & flags:
parts.append(hex( flags & ~flags_done ) )
# Now the key name.
if vk is None:
parts.append("<Unknown scan code>")
else:
try:
parts.append(key_code_to_name[vk])
except KeyError:
# Not in our virtual key map - ask Windows what character this
# key corresponds to.
scancode = win32api.MapVirtualKey(vk, MAPVK_VK_TO_CHAR)
parts.append(chr(scancode))
sep = "+"
if sep in parts: sep = "-"
return sep.join([p.capitalize() for p in parts])
def _psc(char):
sc, mods = get_vk(char)
print("Char %s -> %d -> %s" % (repr(char), sc, key_code_to_name.get(sc)))
def test1():
for ch in """aA0/?[{}];:'"`~_-+=\\|,<.>/?""":
_psc(ch)
for code in ["Home", "End", "Left", "Right", "Up", "Down", "Menu", "Next"]:
_psc(code)
def _pkn(n):
vk, flags = parse_key_name(n)
print("%s -> %s,%s -> %s" % (n, vk, flags, make_key_name(vk, flags)))
def test2():
_pkn("ctrl+alt-shift+x")
_pkn("ctrl-home")
_pkn("Shift-+")
_pkn("Shift--")
_pkn("Shift+-")
_pkn("Shift++")
_pkn("LShift-+")
_pkn("ctl+home")
_pkn("ctl+enter")
_pkn("alt+return")
_pkn("Alt+/")
_pkn("Alt+BadKeyName")
_pkn("A") # an ascii char - should be seen as 'a'
_pkn("a")
_pkn("Shift-A")
_pkn("Shift-a")
_pkn("a")
_pkn("(")
_pkn("Ctrl+(")
_pkn("Ctrl+Shift-8")
_pkn("Ctrl+*")
_pkn("{")
_pkn("!")
_pkn(".")
if __name__=='__main__':
test2()