SendInput function (Windows)

Switch View :
ScriptFree
SendInput function

Applies to: desktop apps only

Synthesizes keystrokes, mouse motions, and button clicks.

Syntax

UINT WINAPI SendInput(
  __in  UINT nInputs,
  __in  LPINPUT pInputs,
  __in  int cbSize
);

Parameters

nInputs [in]

Type: UINT

The number of structures in the pInputs array.

pInputs [in]

Type: LPINPUT

An array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.

cbSize [in]

Type: int

The size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the function fails.

Return value

Type: UINT

The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. If the function returns zero, the input was already blocked by another thread. To get extended error information, call GetLastError.

This function fails when it is blocked by UIPI. Note that neither GetLastError nor the return value will indicate the failure was caused by UIPI blocking.

Remarks

This function is subject to UIPI. Applications are permitted to inject input only into applications that are at an equal or lesser integrity level.

The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.

This function does not reset the keyboard's current state. Any keys that are already pressed when the function is called might interfere with the events that this function generates. To avoid this problem, check the keyboard's state with the GetAsyncKeyState function and correct as necessary.

Because the touch keyboard uses the surrogate macros defined in winnls.h to send input to the system, a listener on the keyboard event hook must decode input originating from the touch keyboard. For more information, see Surrogates and Supplementary Characters.

Requirements

Minimum supported client

Windows 2000 Professional

Minimum supported server

Windows 2000 Server

Header

Winuser.h (include Windows.h)

Library

User32.lib

DLL

User32.dll

See also

Reference
INPUT
GetAsyncKeyState
keybd_event
mouse_event
Conceptual
Keyboard Input
Surrogates and Supplementary Characters

 

 

Send comments about this topic to Microsoft

Build date: 3/6/2012

Community Content

John Bart
Why not use SendKeys?
I use C# and SendKeys.Send("string to send to application") right after using AppActivate to activate the application.  While this does not prevent the user or the system from altering focus away from what you are doing, if you activate the app or setforegroundwindow (however you want to set focus) right before you send the keys, odds are you will be ok.  I also use a Win32 API call to move the mouse cursor... Looks way simpler than this SendInput function.  Maybe I'm wrong, maybe the SendInput is amazingly easy.  Google: "MSDN SendKeys" and you will be able to familiarize yourself with how to press key combinations and how to press special keys programmatically.

Sailing Through
Inquiring on additional features for Windows 7.
This is the first time I have utilized this feature. To be honest, my internet skills are as minmal just as my knowledge is for uses of the array of tools microsoft has given to thousands! I am concerned about not having an 'office program' other than notepad. Any suggesstions? Thank you. Sailing Through.

Julynessi
SendInput - VB.Net Example
Imports System.Runtime.InteropServices

Module SendInput

    Const ShiftKey As Short = 16
    Const ControlKey As Short = 17
    Const AltKey As Short = 18

    Public Function GetKeyboardCode(ByVal value As Char) As Int32
        Dim scan = BitConverter.GetBytes(NativeMethods.VkKeyScan(value))
        Return CInt(scan(0))
    End Function

    Public Function SendStringKeys(ByVal data As String) As Boolean
        If data Is Nothing Then Throw New ArgumentNullException("data")
        Dim tempList = New List(Of tagINPUT)
        For Each item As Char In data
            Dim scan = BitConverter.GetBytes(NativeMethods.VkKeyScan(item))
            Select Case scan(1)
                Case Is = 1 'Contain Shift
                    tempList.Add(GetKeyDownStructure(ShiftKey))
                    tempList.Add(GetKeyDownStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(ShiftKey))
                Case Is = 2 ' Contain Ctrl
                    tempList.Add(GetKeyDownStructure(ControlKey))
                    tempList.Add(GetKeyDownStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(ControlKey))
                Case Is = 4 ' Contain Alt
                    tempList.Add(GetKeyDownStructure(AltKey))
                    tempList.Add(GetKeyDownStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(AltKey))
                Case Else
                    tempList.Add(GetKeyDownStructure(CShort(scan(0))))
                    tempList.Add(GetKeyUpStructure(CShort(scan(0))))
            End Select
        Next
        Dim objSend = tempList.ToArray
        Dim nInput = CUInt(objSend.Count)
        Return nInput = NativeMethods.SendInput(CUInt(objSend.Count), objSend, Marshal.SizeOf(GetType(tagINPUT)))
    End Function

    Public Function SendKeyPress(ByVal key As Int32) As Boolean
        If ValidateKeyCode(key) = False Then Throw New ArgumentOutOfRangeException("key")
        Dim objSend() As tagINPUT = {GetKeyDownStructure(CShort(key)), GetKeyUpStructure(CShort(key))}
        Dim nInput = CUInt(objSend.Count)
        Return nInput = NativeMethods.SendInput(CUInt(objSend.Count), objSend, Marshal.SizeOf(GetType(tagINPUT)))
    End Function

    Public Function SendKeyUp(ByVal key As Int32) As Boolean
        If ValidateKeyCode(key) = False Then Throw New ArgumentOutOfRangeException("key")
        Dim objSend = New tagINPUT(0) {GetKeyUpStructure(CShort(key))}
        Dim nInput = CUInt(objSend.Count)
        Return nInput = NativeMethods.SendInput(CUInt(objSend.Count), objSend, Marshal.SizeOf(GetType(tagINPUT)))
    End Function

    Public Function SendKeyDown(ByVal key As Int32) As Boolean
        If ValidateKeyCode(key) = False Then Throw New ArgumentOutOfRangeException("key")
        Dim objSend = New tagINPUT(0) {GetKeyDownStructure(CShort(key))}
        Dim nInput = CUInt(objSend.Count)
        Return nInput = NativeMethods.SendInput(CUInt(objSend.Count), objSend, Marshal.SizeOf(GetType(tagINPUT)))
    End Function

 
    Private Function GetKeyDownStructure(ByVal key As Short) As tagINPUT
        Dim retVal = New tagINPUT With {.dwType = INPUTTYPE.KEYBOARD}
        With retVal.union.ki
            .dwExtraInfo = Nothing
            .dwFlags = 0
            .time = 0
            .wScan = 0
            .wVk = key
        End With
        Return retVal
    End Function

    Private Function GetKeyUpStructure(ByVal key As Short) As tagINPUT
        Dim retVal = New tagINPUT With {.dwType = INPUTTYPE.KEYBOARD}
        With retVal.union.ki
            .dwExtraInfo = Nothing
            .dwFlags = KEYEVENTF.KEYUP
            .time = 0
            .wScan = 0
            .wVk = key
        End With
        Return retVal
    End Function

    Public Function ValidateKeyCode(ByVal key As Int32) As Boolean
        If key < 1 OrElse key > 254 Then Return False
        Return True
    End Function

 
#Region "Structures"

    <StructLayout(LayoutKind.Sequential)>
    Friend Structure tagHARDWAREINPUT
        Public uMsg As Int32
        Public wParamL As Int16
        Public wParamH As Int16
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Friend Structure tagKEYBDINPUT
        Public wVk As Int16
        Public wScan As Int16
        Public dwFlags As KEYEVENTF
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Friend Structure tagMOUSEINPUT
        Public dx As Int32
        Public dy As Int32
        Public mouseData As Int32
        Public dwFlags As MOUSEEVENTF
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Friend Structure tagINPUT
        Public dwType As INPUTTYPE
        Public union As UnionTag
        <StructLayout(LayoutKind.Explicit)>
        Public Structure UnionTag
            <FieldOffset(0)> Public mi As tagMOUSEINPUT
            <FieldOffset(0)> Public ki As tagKEYBDINPUT
            <FieldOffset(0)> Public hi As tagHARDWAREINPUT
        End Structure
    End Structure

#End Region

#Region "Enumerations"

    Friend Enum INPUTTYPE As UInt32
        MOUSE = 0
        KEYBOARD = 1
        HARDWARE = 2
    End Enum

    <Flags()>
    Friend Enum MOUSEEVENTF As UInt32
        MOVE = &H1  ' mouse move
        LEFTDOWN = &H2  ' left button down
        LEFTUP = &H4  ' left button up
        RIGHTDOWN = &H8  ' right button down
        RIGHTUP = &H10  ' right button up
        MIDDLEDOWN = &H20  ' middle button down
        MIDDLEUP = &H40  ' middle button up
        XDOWN = &H80  ' x button down
        XUP = &H100  ' x button down
        WHEEL = &H800  ' wheel button rolled
        HWHEEL = &H1000  ' hwheel button rolled
        MOVE_NOCOALESCE = &H2000  ' do not coalesce mouse moves
        VIRTUALDESK = &H4000  ' map to entire virtual desktop
        ABSOLUTE = &H8000  ' absolute move
    End Enum

    <Flags()>
    Friend Enum KEYEVENTF As UInt32
        EXTENDEDKEY = &H1
        KEYUP = &H2
        UNICODE = &H4
        SCANCODE = &H8
    End Enum

#End Region

    Private NotInheritable Class NativeMethods
        Private Sub New()
        End Sub

        Private Const WinUser As String = "user32.dll"

        <DllImport(WinUser, EntryPoint:="SendInput", SetLastError:=True)>
        Public Shared Function SendInput(<[In]()> ByVal nInput As UInt32,
                                         <[In](), MarshalAs(UnmanagedType.LPArray, ArraySubtype:=UnmanagedType.Struct, SizeParamindex:=0)> ByVal pInputs() As tagINPUT,
                                         <[In]()> ByVal cbInput As Int32) As UInt32
        End Function

        <DllImport(WinUser, EntryPoint:="VkKeyScan", SetLastError:=True)>
        Public Shared Function VkKeyScan(<[In]()> ByVal ch As Char) As UInt16
        End Function

    End Class

End Module

Rigamonk
C# SendInput/Union
I wound up using this method for simulating the union in c#

/****************** replicated structs for mouse, keys and hardware.  ******************/
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
} ;

[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
} ;

[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}

/****************** then a struct of structs for the union (each in its place): ******************/
[StructLayout(LayoutKind.Explicit)]
internal struct UNION
{
[FieldOffset(0)] public MOUSEINPUT mouseInput;
[FieldOffset(1)] public KEYBDINPUT keyboardInput;
[FieldOffset(2)] public HARDWAREINPUT hardwareInput;
} ;

/****************** Then Passing in the INPUT struct by ref ******************/
[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
public int type;
public UNION union;
} ;

AntiLamer
If you looking for a good managed wrapper
try http://inputsimulator.codeplex.com/

verdy.p
Better use keybd_event, mouse_event in VB6
In VB6, it is still better and simpler to use keybd_event() and mouse_event(), because they don't need the declaration of structures and to manage the translation into an union with array copies (these functions should have not been superseded, and there should even have been another function for sending hardware-input events).

The only interest of SendInput() is that it allows to serialize multiple input events in a single unbroken sequence where you can also mis the various types of input events in a row. But there's no way to support it corectly in correctly managed code.

So instead, there should exist an helper API for managed code (in VB, C#, J#...) that allows opening a stream to which we write each type of events (allocating and building the array internally), and then a flush() function that will finalize the array, send the the input events, and then reset the storage to zero events, and a close() function that will flush the storage (if it stil contains events) and deallocate it.

The other solution would be to have an API such as begin_input() that will delay all input submissions within the calling thread (using the existing keybd_event() and mouse_event() functions and an additional hwinput_event() fution) to internally create the INPUT array, and an end_input() function that will effectively generate the internal call to SendInput(), flushing and deallocating the array at the same time, and returning the number of INPUT entries that have been processed (just from the result of SendInput().

SendInput() used in managed code can easily cause security problems due to the unsafe handling of byte arrays to perform the serialization.

May be you could also define SendInputEx() taking as parameter a new manageable generic type that can contain all fields from all possible event types in a single structure without any union. You would internally translate an array of such new structure into the existing structure, by working "in situ" (overwriting the content of the new array type to generate the old array type).

Or SendInput() could define a new flag value to specify that structure type common to all kind of input events.

Really, such union types in the Win32 API is a nightmare for managed code. But if you really want to support them, PLEASE describe a way to (and simply) declare safe union types (i.e. union types preceded by a declared type id field, with a constant assigned to each subtype, or with a predicate that will be checked before reading/writing any member in the union). E.g. in a VB-like language extension :

Declare Type myType
Dim type As Long
Begin Union
Case type = 1 Then 'This is a checked predicate
Dim field1_1 As MyType1
Case type = 2 Then 'This is another checked predicate
Dim field2_1, field2_2 As MyType2
Dim field2_3 As Long
End Union
End MyType


verdy.p
No union types in VB6
You cannot declare this:

Private Type INPUT_DATA
type As Long
mi As MOUSEINPUT
ki As KEYBDINPUT
hi As HARDWAREINPUT
End Type

The reason is that the mi, ki, hi fields must share the same offset, as they are in an union, sharing the same storage space (with extra padding for the shortest structure). Unfortunately, there's no support for union types in VB6, so you'll have to use managed code to build the INPUT_DATA using Array.Copy() within a Byte array declared as:

Dim inputData(Len(Long) + Max(Len(MOUSEINPUT), Len(KEYBDINPUT), Len(HARDWAREINPUT))) As Byte

verdy.p
VB6 Problem
[delete]

Thomas Lee
proper include
You have to include WinAble.h not WinUser.h

Thomas Lee
Bug: Appears '^6' instead of '6'
// IMPORTANT: Current keyboard layout 0xf0010413 (Netherland with USA kbd)!!!!!!!
WORD vkCode = 0x36; // '6'
INPUT keyEvent = {0};
keyEvent.type = INPUT_KEYBOARD;
keyEvent.ki.wVk = vkCode;
keyEvent.ki.wScan = MapVirtualKeyEx(vkCode, 0, (HKL)0xf0010413);
SendInput(1, &amp;keyEvent, sizeof(keyEvent));
///////////////////////////////////////////////

This code gives the '^6' char combination instead of '6'.

longtimeUser
It should take one line to do this.
It should take one line for keyboard input. Most of the times I've ever needed to do something with keyboard input I end up repeating the same code over and over. I am a C++ user, and I would like an example. This document is almost as meaningless to a person uneducated about Scan codes as the GetAsyncKeyState page. I'm sure someone at Microsoft would gladly show the world how this is properly done. Abstraction can mean a lot with old languages.

noone123457890
Old DOS Applications
If you want to send keyboard input to very old applications (e.g. DOS applications) you should use keybd_event with appropriate INT 9 Make/Break codes.

juicejams
WM_TOUCH
Will WM_TOUCH messages work with SendInput?
For example:

reset.mi.dwFlags = (MOUSEEVENTF_LEFTDOWN)

to be replaced with

reset.mi.dwFlags = (TOUCHEVENTF_DOWN)

SendInput(1,&reset,sizeof(reset));

?

Thank you

Nice PPk
The ki, hi, mi share memory in INPUT structure
I don't know how to define a union in VB. You may try to seperate them in three VB struct, as below.

Private Type INPUT_MOUSE_DATA
type As Long
mi As MOUSEINPUT
End Type

Private Type INPUT_KEYBD_DATA
type As Long
ki As KEYBDINPUT
End Type

Private Type INPUT_HW_DATA
type As Long
hi As HARDWAREINPUT
End Type