holy cow On Mon, May 1, 2017 at 8:02 PM eryk sun <eryk...@gmail.com> wrote:
> 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