On Mon, May 1, 2017 at 6:28 PM, Michael C <mysecretrobotfact...@gmail.com> wrote: > Hi all, I found out that one way to press ESC to kill the script was to use > my previous > script language, AutoHotKey and this is how it works: > > AutoHotKey code > ## function that kills the window with title '*Python 3.6.1 Shell*' > > kill() > { > WinKill, *Python 3.6.1 Shell* > } > > ## When ESC is pressed, runs the function 'kill' > Esc::kill() > > Yes, that's the entire script. > Is there a way to write it in Python on windows?
Instead of using a hotkey, you can set a global low-level keyboard hook. Then optionally you can check for a particular foreground window before handling the key. For example: import ctypes import win32con import win32gui from ctypes import wintypes user32 = ctypes.WinDLL('user32', use_last_error=True) VK_ESCAPE = 0x1B LLKHF_EXTENDED = 0x00000001 LLKHF_LOWER_IL_INJECTED = 0x00000002 LLKHF_INJECTED = 0x00000010 LLKHF_ALTDOWN = 0x00000020 LLKHF_UP = 0x00000080 ULONG_PTR = wintypes.WPARAM class KBDLLHOOKSTRUCT(ctypes.Structure): _fields_ = (('vkCode', wintypes.DWORD), ('scanCode', wintypes.DWORD), ('flags', wintypes.DWORD), ('time', wintypes.DWORD), ('dwExtraInfo', ULONG_PTR)) HOOKPROC = ctypes.WINFUNCTYPE(wintypes.LPARAM, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM) user32.SetWindowsHookExW.restype = wintypes.HHOOK user32.SetWindowsHookExW.argtypes = ( ctypes.c_int, # _In_ idHook HOOKPROC, # _In_ lpfn wintypes.HINSTANCE, # _In_ hMod wintypes.DWORD) # _In_ dwThreadId user32.CallNextHookEx.restype = wintypes.LPARAM user32.CallNextHookEx.argtypes = ( wintypes.HHOOK, # _In_opt_ hhk ctypes.c_int, # _In_ nCode wintypes.WPARAM, # _In_ wParam wintypes.LPARAM) # _In_ lParam def keyboard_hook(handler, hwnd=None): @HOOKPROC def hookfunc(nCode, wParam, lParam): event = KBDLLHOOKSTRUCT.from_address(lParam) if hwnd is not None and win32gui.GetForegroundWindow() == hwnd: handler(event) return user32.CallNextHookEx(hHook, nCode, wParam, lParam) hHook = user32.SetWindowsHookExW(win32con.WH_KEYBOARD_LL, hookfunc, None, 0) if not hHook: raise ctypes.WinError(ctypes.get_last_error()) win32gui.PumpMessages() if __name__ == '__main__': import msvcrt import threading import win32console print('Press escape to quit') def escape_handler(event): if event.vkCode == VK_ESCAPE: # kill the hook thread win32gui.PostQuitMessage(0) elif not (event.flags & LLKHF_UP): print('Virtual Key Code: {:#04x} [{}]'.format(event.vkCode, event.time)) t = threading.Thread(target=keyboard_hook, args=(escape_handler, win32console.GetConsoleWindow()), daemon=True) t.start() # consume keyboard input while t.is_alive(): if msvcrt.kbhit(): msvcrt.getwch() The __main__ demo should be run as a console script. The keyboard hook filters on the console window handle from GetConsoleWindow(). _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor