[python-win32] Help on using win32api.SendMessage to send keystrokes

Daniel F nanotube at gmail.com
Thu Apr 7 00:53:42 CEST 2005

Well... i tried it... and sendinput officially does not work on ff7
(but does on notepad). so either ff7 is doing something really funky
(not likely, since it does load dinput.dll), or sendinput is not
actually upstream of directinput (more likely). but the only game i
have that loads dinput.dll is ff7, so cant test on anything else to
make sure...

(amazingly, unrealtournament, which i also have, does not load
dinput.dll, and sendinput, as well as postmessage, work with it. i
wonder why a real-time game such as ut has no problems going through
the usual message queue, but ff7, which in a slow-paced rpg, is using
directinput. like.... wtf, you know? :) )

so if anyone has any games to test with, here is the sendinput code.
it tries sending the up arrow key press. so if anyone wants to test,
just get to a screen in the game where you will clearly see the
results of the up arrow key press, alt-tab out of it, run the python
script, and alt-tab back into the game, and wait for the event (you
have 10 seconds). of course, if your game doesnt use the arrow keys...
you can change the prog to send whatever key you need it to. ;)

### begin code
from ctypes import *
import time

PUL = POINTER(c_ulong)
class KeyBdInput(Structure):
    _fields_ = [("wVk", c_ushort),
                ("wScan", c_ushort),
                ("dwFlags", c_ulong),
                ("time", c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(Structure):
    _fields_ = [("uMsg", c_ulong),
                ("wParamL", c_short),
                ("wParamH", c_ushort)]

class MouseInput(Structure):
    _fields_ = [("dx", c_long),
                ("dy", c_long),
                ("mouseData", c_ulong),
                ("dwFlags", c_ulong),
                ("dwExtraInfo", PUL)]
class Input_I(Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(Structure):
    _fields_ = [("type", c_ulong),
                ("ii", Input_I)]

if __name__ == '__main__':
    for i in xrange(1,11):
        print i
    FInputs = Input * 1
    extra = c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0x26, 0x48, 0, 0, pointer(extra) )
    x = FInputs( ( 1, ii_ ) )
    print sizeof(x[0])
    print windll.user32.SendInput(1, pointer(x), sizeof(x[0]))
    print "err",windll.kernel32.GetLastError()

### end code
> I don't know the answer to this.  Games tend to be straight-to-the-metal
> applications: they don't truck with a lot of filtering and intermediate
> DLLs.  You might be able to use the debug APIs to watch for the loading
> of the DirectInput DLL and insert some manual hooks, but that's a pretty
> high level of guruness.  Google for "api dll injection".

i guess either im officially dead in the water with this project, or i
learn how to do dll injection... (good thing this is a personal
project, nobody is nipping at my heels with a deadline)

> >also, regarding the use of scancodes... looks like python win32 doesnt
> >wrap MapVirtualKey (to convert form vk to scancode) either. i suppose
> >ctypes should help me out with this one, too?
> ctypes is a wonderful package -- invaluable for someone doing Win32 API
> work.  Basically, it allows you to call any API in any DLL, as long as
> you can describe the parameters.

except mapvirtualkey. not that it matters now, anyway, but, behold this:

# ##code:
from ctypes import *
import time

sc = windll.user32.MapVirtualKey(0x41, 0)
print sc
# ##end code

Traceback (most recent call last):
  File "C:\Documents and Settings\dfolkins\Desktop\python
scripts\mapvirtualkey.py", line 4, in ?
    sc = windll.user32.MapVirtualKey(0x41, 0)
  File "C:\Python24\Lib\site-packages\ctypes\__init__.py", line 366,
in __getattr__
    func = self._StdcallFuncPtr(name, self)
AttributeError: function 'MapVirtualKey' not found
###end output

so... even though i dont care about mapvirtualkey per se, i wonder
what gives... any ideas?

and... if anyone ever happens upon a way to hook and inject events
upstream of directinput in a nice api-like way, please let me know,
eh? :)

Thank you,
Daniel, off to learn how to inject dll....

More information about the Python-win32 mailing list