I'm trying to send DirectInput (through DirectX) keyboard inputs to a program I'm running. I've got it working alright when the program is active; e.g. repeatedly typing "A" in the program repeatedly. But this doesn't work if the program is minimized, and whatever else I want to do is interrupted by a stream of 'A's.
So I want to send keyboard inputs to the program even as it remains in the background. I've looked into the win32 library, with functions PostMessage and SendMessage, which should send input to a program handle (a handle found with another win32 function). I can get the handle of programs alright now, but the keyboard inputs never apparently get sent.
For instance;
import win32gui
import win32con
import win32api
hwndMain = win32gui.FindWindow(None, "Program Window Name")
win32api.PostMessage(hwndMain, win32con.WM_CHAR,'A',0)
this code snippet should just hit the letter 'A' in the program being handled, but nothing happens.
For reference, the code I use for DirectInput to the program is;
import ctypes
import time
SendInput = ctypes.windll.user32.SendInput
A = 0x1E
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def PressKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))
x = Input(ctypes.c_ulong(1), ii_)
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008 | 0x0002, 0,
ctypes.pointer(extra))
x = Input(ctypes.c_ulong(1), ii_)
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
if __name__ == '__main__':
time.sleep(10)
while (True):
PressKey(A)
time.sleep(1)
ReleaseKey(A)
time.sleep(2)
But as I've mentioned, this only works when the window is active, such that the PC cannot really be used for anything else in the meantime. It may be that it is impossible to combine the Background-program PostMessage with the DirectInput functions, but right now I cannot even get PostMessage to work with something simple, like posting a character to my Python editor itself (Spyder (Python 3.8)).
I've already looked across several threads on this issue, but nothing I've found seems to work; 1 2 3 4