My application sends a mouse click to an area of the screen outside my console window using win32api.mouse_event
. This causes my window to lose focus so I can't detect key presses using msvcrt.kbhit.
My question is, how to implement something like this with the console window not being visible/active?
EDIT:
Here is example code. This is just a basic console version. If the console disappears, set it so that it stays on top. Once it clicks outside of the console (100,100), pressing the Esc key will not break out of loop. How would one implement a break for a problem such as this?
import msvcrt, win32api, win32con
pixelx = 100
pixely = 100
win32api.SetCursorPos((pixelx,pixely))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,pixelx,pixely,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,pixelx,pixely,0,0)
while 1:
print 'Testing..'
# body of the loop ...
if msvcrt.kbhit():
if ord(msvcrt.getch()) == 27:
break
I can see 3 possible ways of doing this. The first, would be to bring your window to the top after the mouse click, however I assume this is not what you want to happen.
A second way, which should work fine if all you want is the ESC key, would be to use a hotkey. This could be done using a method similar to this:
import win32con, ctypes, ctypes.wintypes
def esc_pressed():
print("Escape was pressed.")
ctypes.windll.user32.RegisterHotKey(None, 1, 0, win32con.VK_ESCAPE)
try:
msg = ctypes.wintypes.MSG()
while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
esc_pressed()
ctypes.windll.user32.TranslateMessage(ctypes.byref(msg))
ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg))
finally:
ctypes.windll.user32.UnregisterHotKey(None, 1)
For more information on registering a hotkey with Python you can look here.
The third way, which you would have to use if you wanted to catch every key press, would be to set a low level keyboard hook.
来源:https://stackoverflow.com/questions/15777719/how-to-detect-key-press-when-the-console-window-has-lost-focus