Home > Windows API > How to use SendInput?

How to use SendInput?

So what does SendInput API do?

SendInput API is a helper function to simulate keyboard and mouse inputs. It’s an ideal function to insert characters into a password which otherwise is not possible. Here is what MSDN says about this function…

“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.”

Here is a simple and basic function which sends a given text to a foreground window (my earlier function was crap so I replaced it with this new one that works for all texts, haven’t tried out with foreign keyboards though)…

BOOL SendText( LPCSTR lpctszText )
{
   vector< INPUT > EventQueue;

   char Buff[120] = {0};
   GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, Buff, sizeof(Buff));
   HKL hKeyboardLayout = ::LoadKeyboardLayout( Buff, KLF_ACTIVATE );

   const int Len = strlen( lpctszText );
   for( int Index = 0; Index &amp;amp;amp;lt; Len; ++Index )
   {
      INPUT Event = { 0 };

      const SHORT Vk = VkKeyScanEx(lpctszText[Index], hKeyboardLayout);
      const UINT VKey = ::MapVirtualKey( LOBYTE( Vk ), 0 );

      if( HIBYTE( Vk ) == 1 ) // Check if shift key needs to be pressed for this key
      {
          // Press shift key
          ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
          Event.type = INPUT_KEYBOARD;
          Event.ki.dwFlags = KEYEVENTF_SCANCODE;
          Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 );
          EventQueue.push_back( Event );
      }

      // Keydown
      ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
      Event.type = INPUT_KEYBOARD;
      Event.ki.dwFlags = KEYEVENTF_SCANCODE;
      Event.ki.wScan = VKey;
      EventQueue.push_back( Event );

      // Keyup
      ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
      Event.type = INPUT_KEYBOARD;
      Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
      Event.ki.wScan = VKey;
      EventQueue.push_back( Event );

      if( HIBYTE( Vk ) == 1 )// Release if previouly pressed
      {
           // Release shift key
          ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
          Event.type = INPUT_KEYBOARD;
          Event.ki.dwFlags = KEYEVENTF_SCANCODE| KEYEVENTF_KEYUP;
          Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 );
          EventQueue.push_back( Event );
      }
   }// End for

   if( hKeyboardLayout )
   {
       UnloadKeyboardLayout( hKeyboardLayout );
   }

   return ::SendInput( EventQueue.size(), &amp;amp;amp;amp;EventQueue[0], sizeof( INPUT ));
}
Advertisements
  1. Dark Alchemist
    August 16, 2009 at 5:53 pm

    Very odd. My routine that works has a ton more code than yours just to get the special chars. No idea why that is either.

  2. Dark Alchemist
    August 13, 2009 at 5:52 am

    Doesn’t do capital letters and that is where I am having the difficulty with. Followed all sorts of code samples but the best I could manage to do is all caps or all lowercase but not a mixture.

    • August 13, 2009 at 10:25 am

      Yes you are right. I’ll update the code to fix this. What you need to do simulate a shift key down and a shift key up after inserting an capital letter to event queue vector. Bit lazy on my part.

    • Dark Alchemist
      August 13, 2009 at 11:06 am

      Do you happen to know why SendInput would work in some programs and not others since it is simulating an actual key press?

      • August 13, 2009 at 4:19 pm

        It should work in all cases, I’m not aware of any exceptions. Make sure the control being discussed here has the input focus.

        • Dark Alchemist
          August 13, 2009 at 5:16 pm

          Trust me I did a lot of googling and I am not the only one having this issue. Seems really weird but I think, after looking at all those sites from Google, that DirectInput kills it. Right now I am trying to automate something in a game I play and lower case works but not ever uppercase. keybd_event nor SendInput work in it but both work for all other programs. keybd_event, after doing so much reading, is now just a wrapper for SendInput but I am just parroting what I read about that part.

          • Dark Alchemist
            August 13, 2009 at 5:18 pm

            Wanted to clarify it isn’t just uppercase it is any key that demand the shift. Seems really weird for it to not work when SendInput is supposed to be the lowest level method that inserts my keys at the hardware level.

            • August 13, 2009 at 5:37 pm

              Try turning on caps lock of course then turn it off too. 😉

              • Dark Alchemist
                August 13, 2009 at 5:57 pm

                Did that as a first recourse and that didn’t work either. What is funny is I can run all of this and hold down the shift key and it works 90% (some slip by).

                • August 13, 2009 at 8:11 pm

                  🙂

                  • Dark Alchemist
                    August 13, 2009 at 10:02 pm

                    I finally was able to get keybd_event to work and SendInput as well but what you can’t do is do the VK_SHIFT then char down and up then VK_SHIFT up. You have to delay after the shift down and before the shift up or no go.

                    • August 14, 2009 at 10:46 am

                      Mm. Thanks for the info.

                    • August 14, 2009 at 5:15 pm

                      Hello,

                      Can you try again with this new function. My earlier function was full of bugs. Now I’ve replaced it with a new one. Now shift key is properly handled. Please let me know if it works.

                    • Dark Alchemist
                      August 14, 2009 at 8:06 pm

                      I haven’t tried it but I can tell you it doesn’t handle shift characters and there is no need for so many SendInput statements (3 is all that you need).

                    • Dark Alchemist
                      August 14, 2009 at 10:05 pm

                      I tried it and it did not work for shifting the chars (!@#$%, etc…) but did shift the capital letters.

                    • August 16, 2009 at 4:41 pm

                      For me it shifts them correctly.

                • September 21, 2009 at 7:04 pm

                  Can you try again. It’s been sometime though. Did make some small changes.

                  Just wanted to know if it works. 🙂

  3. Sarath
    August 5, 2009 at 6:53 am

    Hi,
    Good post. The snippet is really handy.

  1. January 6, 2011 at 2:46 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: