Reputation: 33
I used the below to get the Window Handle of an app and bring it to be the focus. I want to type in a string of characters into the app. But using win32api.keybd_event, I am able to type in only single characters? Is there a way to type in a string of characters?
Eg, "I am happy"
Thank you
import win32gui
import win32api
import win32con
hld = win32gui.FindWindow (None, "UNTITLED") # Returns the handle of the window titled UNTITLED
if hld>0:
win32gui.SetForegroundWindow(hld)
win32api.keybd_event(0x46, 0, ) # F
Upvotes: 1
Views: 2820
Reputation: 3890
You can use the SendInput
function to achieve this. Send the string you need to send to the corresponding window once through this function.
I created a sample as follows:
import ctypes as ct
from win32con import SW_MINIMIZE, SW_RESTORE
from win32ui import FindWindow, error as ui_err
from time import sleep
class cls_KeyBdInput(ct.Structure):
_fields_ = [
("wVk", ct.c_ushort),
("wScan", ct.c_ushort),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]
class cls_HardwareInput(ct.Structure):
_fields_ = [
("uMsg", ct.c_ulong),
("wParamL", ct.c_short),
("wParamH", ct.c_ushort)
]
class cls_MouseInput(ct.Structure):
_fields_ = [
("dx", ct.c_long),
("dy", ct.c_long),
("mouseData", ct.c_ulong),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]
class cls_Input_I(ct.Union):
_fields_ = [
("ki", cls_KeyBdInput),
("mi", cls_MouseInput),
("hi", cls_HardwareInput)
]
class cls_Input(ct.Structure):
_fields_ = [
("type", ct.c_ulong),
("ii", cls_Input_I)
]
def make_input_objects( l_keys ):
p_ExtraInfo_0 = ct.pointer(ct.c_ulong(0))
l_inputs = [ ]
for n_key, n_updown in l_keys:
ki = cls_KeyBdInput( n_key, 0, n_updown, 0, p_ExtraInfo_0 )
ii = cls_Input_I()
ii.ki = ki
l_inputs.append( ii )
n_inputs = len(l_inputs)
l_inputs_2=[]
for ndx in range( 0, n_inputs ):
s2 = "(1, l_inputs[%s])" % ndx
l_inputs_2.append(s2)
s_inputs = ', '.join(l_inputs_2)
cls_input_array = cls_Input * n_inputs
o_input_array = eval( "cls_input_array( %s )" % s_inputs )
p_input_array = ct.pointer( o_input_array )
n_size_0 = ct.sizeof( o_input_array[0] )
return ( n_inputs, p_input_array, n_size_0 )
def send_input( window1, t_inputs,):
tpl1 = window1.GetWindowPlacement()
window1.SetForegroundWindow()
sleep(0.2)
window1.SetFocus()
sleep(0.2)
rv = ct.windll.user32.SendInput( *t_inputs )
return rv
def test():
#t_hello is "hello\n"
t_hello = ( ( 0x48, 0 ), ( 0x45, 0 ), ( 0x4C, 0 ), ( 0x4C, 0 ), ( 0x4F, 0 ), ( 0x0D, 0 ), )
l_keys = [ ]
l_keys.extend( t_hello )
s_app_name = "Notepad"
window1 = FindWindow( s_app_name, None )
if window1 == None:
print( "%r has no window." % s_app_name )
input( 'press enter to close' )
exit()
t_inputs = make_input_objects( l_keys )
n = send_input( window1, t_inputs )
if __name__ == '__main__':
test()
This sample implements sending the string "hello" to the notepad. And it works fine for me.
Upvotes: 1