parameters: (string_to_type,
                 use_modifiers=False,
                 keystroke_time=0,
                 time_between_keystrokes=0)
docstring: Simulate typing a string on the keyboard.
  
    Args:
      string_to_type: the string to print
      use_modifiers: specifies whether the following modifier characters
        should be active:
        {abc}: type characters with ALT held down
        [abc]: type characters with CTRL held down
        \ escapes {}[] and treats these values as literal
        standard escape sequences are valid even if use_modifiers is false
        \p is "pause" for one second, useful when driving menus
        \1-\9 is F-key, \0 is F10
  
        TODO(jhaas): support for explicit control of SHIFT, support for
                     nonprintable keys (F-keys, ESC, arrow keys, etc),
                     support for explicit control of left vs. right ALT or SHIFT,
                     support for Windows key
  
      keystroke_time: length of time (in secondes) to "hold down" the key
      time_between_keystrokes: length of time (seconds) to pause between keys
  
    Returns:
      None
docstring_summary: Simulate typing a string on the keyboard.
docstring_tokens: Simulate typing a string on the keyboard .
function: def TypeString(string_to_type,
                 use_modifiers=False,
                 keystroke_time=0,
                 time_between_keystrokes=0):
    """Simulate typing a string on the keyboard.
  
    Args:
      string_to_type: the string to print
      use_modifiers: specifies whether the following modifier characters
        should be active:
        {abc}: type characters with ALT held down
        [abc]: type characters with CTRL held down
        \ escapes {}[] and treats these values as literal
        standard escape sequences are valid even if use_modifiers is false
        \p is "pause" for one second, useful when driving menus
        \1-\9 is F-key, \0 is F10
  
        TODO(jhaas): support for explicit control of SHIFT, support for
                     nonprintable keys (F-keys, ESC, arrow keys, etc),
                     support for explicit control of left vs. right ALT or SHIFT,
                     support for Windows key
  
      keystroke_time: length of time (in secondes) to "hold down" the key
      time_between_keystrokes: length of time (seconds) to pause between keys
  
    Returns:
      None
    """
  
    shift_held = win32api.GetAsyncKeyState(win32con.VK_SHIFT  ) < 0
    ctrl_held  = win32api.GetAsyncKeyState(win32con.VK_CONTROL) < 0
    alt_held   = win32api.GetAsyncKeyState(win32con.VK_MENU   ) < 0
  
    next_escaped = False
    escape_chars = {
      'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v'}
  
    for char in string_to_type:
      vk = None
      handled = False
  
      # Check to see if this is the start or end of a modified block (that is,
      # {abc} for ALT-modified keys or [abc] for CTRL-modified keys
      if use_modifiers and not next_escaped:
        handled = True
        if char == "{" and not alt_held:
          alt_held = True
          PressKey(True, win32con.VK_MENU)
        elif char == "}" and alt_held:
          alt_held = False
          PressKey(False, win32con.VK_MENU)
        elif char == "[" and not ctrl_held:
          ctrl_held = True
          PressKey(True, win32con.VK_CONTROL)
        elif char == "]" and ctrl_held:
          ctrl_held = False
          PressKey(False, win32con.VK_CONTROL)
        else:
          handled = False
  
      # If this is an explicitly-escaped character, replace it with the
      # appropriate code
      if next_escaped and char in escape_chars: char = escape_chars[char]
  
      # If this is \p, pause for one second.
      if next_escaped and char == 'p':
        time.sleep(1)
        next_escaped = False
        handled = True
  
      # If this is \(d), press F key
      if next_escaped and char.isdigit():
        fkey = int(char)
        if not fkey: fkey = 10
        next_escaped = False
        vk = win32con.VK_F1 + fkey - 1
  
      # If this is the backslash, the next character is escaped
      if not next_escaped and char == "\\":
        next_escaped = True
        handled = True
  
      # If we make it here, it's not a special character, or it's an
      # escaped special character which should be treated as a literal
      if not handled:
        next_escaped = False
        if not vk: vk = win32api.VkKeyScan(char)
  
        # VkKeyScan() returns the scan code in the low byte. The upper
        # byte specifies modifiers necessary to produce the given character
        # from the given scan code. The only one we're concerned with at the
        # moment is Shift. Determine the shift state and compare it to the
        # current state... if it differs, press or release the shift key.
        new_shift_held = bool(vk & (1<<8))
  
        if new_shift_held != shift_held:
          PressKey(new_shift_held, win32con.VK_SHIFT)
          shift_held = new_shift_held
  
        # Type the key with the specified length, then wait the specified delay
        TypeKey(vk & 0xFF, keystroke_time)
        time.sleep(time_between_keystrokes)
  
    # Release the modifier keys, if held
    if shift_held: PressKey(False, win32con.VK_SHIFT)
    if ctrl_held:  PressKey(False, win32con.VK_CONTROL)
    if alt_held:   PressKey(False, win32con.VK_MENU)
function_tokens: def TypeString ( string_to_type , use_modifiers = False , keystroke_time = 0 , time_between_keystrokes = 0 ) : shift_held = win32api . GetAsyncKeyState ( win32con . VK_SHIFT ) < 0 ctrl_held = win32api . GetAsyncKeyState ( win32con . VK_CONTROL ) < 0 alt_held = win32api . GetAsyncKeyState ( win32con . VK_MENU ) < 0 next_escaped = False escape_chars = { 'a' : '\a' , 'b' : '\b' , 'f' : '\f' , 'n' : '\n' , 'r' : '\r' , 't' : '\t' , 'v' : '\v' } for char in string_to_type : vk = None handled = False # Check to see if this is the start or end of a modified block (that is, # {abc} for ALT-modified keys or [abc] for CTRL-modified keys if use_modifiers and not next_escaped : handled = True if char == "{" and not alt_held : alt_held = True PressKey ( True , win32con . VK_MENU ) elif char == "}" and alt_held : alt_held = False PressKey ( False , win32con . VK_MENU ) elif char == "[" and not ctrl_held : ctrl_held = True PressKey ( True , win32con . VK_CONTROL ) elif char == "]" and ctrl_held : ctrl_held = False PressKey ( False , win32con . VK_CONTROL ) else : handled = False # If this is an explicitly-escaped character, replace it with the # appropriate code if next_escaped and char in escape_chars : char = escape_chars [ char ] # If this is \p, pause for one second. if next_escaped and char == 'p' : time . sleep ( 1 ) next_escaped = False handled = True # If this is \(d), press F key if next_escaped and char . isdigit ( ) : fkey = int ( char ) if not fkey : fkey = 10 next_escaped = False vk = win32con . VK_F1 + fkey - 1 # If this is the backslash, the next character is escaped if not next_escaped and char == "\\" : next_escaped = True handled = True # If we make it here, it's not a special character, or it's an # escaped special character which should be treated as a literal if not handled : next_escaped = False if not vk : vk = win32api . VkKeyScan ( char ) # VkKeyScan() returns the scan code in the low byte. The upper # byte specifies modifiers necessary to produce the given character # from the given scan code. The only one we're concerned with at the # moment is Shift. Determine the shift state and compare it to the # current state... if it differs, press or release the shift key. new_shift_held = bool ( vk & ( 1 << 8 ) ) if new_shift_held != shift_held : PressKey ( new_shift_held , win32con . VK_SHIFT ) shift_held = new_shift_held # Type the key with the specified length, then wait the specified delay TypeKey ( vk & 0xFF , keystroke_time ) time . sleep ( time_between_keystrokes ) # Release the modifier keys, if held if shift_held : PressKey ( False , win32con . VK_SHIFT ) if ctrl_held : PressKey ( False , win32con . VK_CONTROL ) if alt_held : PressKey ( False , win32con . VK_MENU )