Solved

Using SendInput to emulate keyboard for MS Windows in "C" not C++

Posted on 2004-09-04
5
944 Views
Last Modified: 2008-02-01
Hello everyone.
                      Some time ago I was helped by EE in my goal to create a program that could send keys to a Microsoft Windows application, ranging from Win 98 to XP.

The program will need to do all sorts of things like copy applications from a CD and then by launching the copied application will send keyboard instructions to it so as to perform the programs install routine that would otherwise take up my time.

I have written much of the program so far but keep getting stuck on the send keys part.

Below is my test code. Would someone please explain to me what I am doing so wrong with the SendInput routine.

Oh. I am developing on a Windows XP Pro SP1 machine using "Wedit Win32 Version 3.3" that uses the "lcc-win32" copiler. When written, however I would like the program to run on any Windows machine from 98 to XP.

Thanks in advance Ralph.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <shellapi.h>

int main(int argc,char *argv[]) {
      if (argc == 1) {
            Beep;
            printf("The program has started\n");
            window_shopping();
            printf("The program has ended\n");
      }
      return 0;
}


void window_shopping(){
      /*Searches for a window and does not release until window is found*/
      printf("Looking for the window\n");
      BOOL bFound = FALSE;
      while (!bFound){
                EnumWindows(EnumWindowsProc, (LPARAM)&bFound);
                if (!bFound){
                    Sleep(250);
            }
            else{
                  bFound = TRUE;
            };
      };
      printf("Found the window and fired keys\n");
}


BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam){
                // Detect the window.
                BOOL bIsOurWindow = FALSE;
      char *sTitle = "";
      GetWindowText (hWnd, sTitle, 255);
      
      if (strcmp("Untitled - Notepad",sTitle) == 0){
            printf("## %s ##\n",sTitle);
            bIsOurWindow = TRUE;
      }
      else{
            // Put this back in to show all window titles encountered
            //printf("%s\n",sTitle);
            BOOL bIsOurWindow = FALSE;
      };

    if (bIsOurWindow){
          INPUT myInputs[2];
      myInputs[0] = KEYBDINPUT{VK_TAB};
      myInputs[1] = {VK_TAB};
          SetFocus(hWnd);
          SendInput(1, myInputs, sizeof(myInputs[0]));
          SendInput(1, 33, sizeof(myInputs[0]));
    };

      return 1;
}
            
0
Comment
Question by:RalphG
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 11

Accepted Solution

by:
KurtVon earned 250 total points
ID: 11982739
I'm a bit surprised this compiled, even if C doesn't have strict type checking.

The most obvious problem is the last SendInput, since 33 is definately not a pointer to an INPUT struct.  You will need to creat an INPT struct for that.

I'd also say the variably myInputs doesn't need to be an array, and it is usually a good idea to set the entire structure, just to be safe.

So I'd change that last bit to

if (bIsOurWindow)
{
    INPUT myInput;

    memset(myInput, 0, sizeof(myInput));
    myInput.type = INPUT_KEYBOARD;
    myInput.ki.wVK = VK_TAB;

    SetFocus(hWnd);
    SendInput(1, &myInput, sizeof(myInput));

    myInput.ki.wVK = 33;
    SendInput(1, &myInput, sizeof(myInput));
}

Hope this helps.
0
 

Author Comment

by:RalphG
ID: 11983478
Thankyou so much for helping KurtVon.

The compile problem is my error all the time, it never compiles, and the "33" was an attempt to use anything other than a correct VK_TAB just to see if I could get any more info from the compile errors, i.e. break the program to help find other breaks etc.

After putting your code in my program I now get the three following compile errors:

"Error C:\lcc\projects\autofix\autofix.c: 30 type error in argument 1 to 'memset'; found 'struct tagINPUT' expected 'pointer to void'"

"Error C:\lcc\projects\autofix\autofix.c: 32 unknown field 'wVK' of struct tagKEYBDINPUT"

"Error C:\lcc\projects\autofix\autofix.c: 37 unknown field 'wVK' of struct tagKEYBDINPUT"

This is typical of the problems I have been having! I am sure the answer is there it just keeps passing me by.

By the way if I put "memset(&myInput, 0, sizeof(myInput));" instead of "memset(myInput, 0, sizeof(myInput));" the first compile error goes away leaving only the two "wKV" errors. Am I correct to create the pointer "&myInput" as shown above?
0
 

Author Comment

by:RalphG
ID: 11983528
Just remembered, the following link appears to explain that I do require an array for the SendInput procedure, atleast that what it says:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/KeyboardInput/KeyboardInputReference/KeyboardInputFunctions/SendInput.asp 
0
 

Author Comment

by:RalphG
ID: 11983654
A ha! The following compiles fine:

if (bIsOurWindow)
{
      INPUT myInput;

          memset(&myInput, 0, sizeof(myInput));
          myInput.type = INPUT_KEYBOARD;
          myInput.ki.wVk = VK_MENU;

          SetFocus(hWnd);
          SendInput(1, &myInput, sizeof(myInput));

          myInput.ki.wVk = VK_DOWN;
          SendInput(1, &myInput, sizeof(myInput));
}

Changes include:
"myInput" becomes "&myInput"          (Note preceding "&")
"wVK" becomes "wVk"                       (Note case)
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 11984508
Whoops.  Sorry about the typos.  Glad it worked out.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question