1

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
5
  • Why are you using this approach instead of UIAutomation? Commented Oct 18, 2020 at 8:05
  • This is part of a larger project that I am doing in Python. So yes, I need to do it in Python Commented Oct 18, 2020 at 8:42
  • Yes. But why are you not using UIAutomation from Python? If you don't yet know what UIAutomation is, then I suggest you look it up. Commented Oct 18, 2020 at 14:29
  • Hi Sorry I thought u were referring to Uipath automation. Anyway I can't use UIAutomation in Python as I don't have the module in Anaconda. I can't install new modules due to restriction in my company IT policy. So I would appreciate it if someone could instruct me how to write a string of char using win32api. Maybe the SendInput function if keybd.event can't work. Thanks Commented Oct 19, 2020 at 0:44
  • That's really your problem. It tends not to make for a very good question here if the answers are constrained in such ways. Commented Oct 19, 2020 at 11:19

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Zhu Song, Many thanks for this. But yr code looks real complicated to me. I think I will stick to win32api.keybd_event but add many lines for each char. However, I noted an issue for double quote that I need to enter . 0xDE is for the 'single-quote/double-quote' key. I need the double quote which is the alternate key on my keyboard. If I use shift key VK_SHIFT, after my prog ends, the shift key on my keyboard get stuck. And I can't un-stuck the shift key unless I restart my comp. So any way for me to enter double quote using keybd_event without all these issues?
@Unknown According to the document.You need to set the dwFlags to 2,like win32api.keybd_event(0x10, 0,2) after you using the shift.
Hi Zhu Song, Thanks for the reply. It seems to work by using win32api.keybd_event(0x10, 0,) win32api.keybd_event(0xDE, 0, ) win32api.keybd_event(0x10, 0, 2). We need to depress then undepress the shift key at the end. The documentation is difficult to understand. Thanks for yr explanation!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.