Link to home
Start Free TrialLog in
Avatar of Granis
Granis

asked on

How to use SendInput

SendInput is declared in winuser.h but somehow I can't use it anyway; I get the error: 'SendInput' : undeclared identifier


Well, I extracted the declarations used for SendInput and put it in a seperate header file which ended up like this:

typedef struct tagMOUSEINPUT {
    LONG    dx;
    LONG    dy;
    DWORD   mouseData;
    DWORD   dwFlags;
    DWORD   time;
    DWORD   dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT, FAR* LPMOUSEINPUT;

typedef struct tagKEYBDINPUT {
    WORD    wVk;
    WORD    wScan;
    DWORD   dwFlags;
    DWORD   time;
    DWORD   dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, FAR* LPKEYBDINPUT;

typedef struct tagHARDWAREINPUT {
    DWORD   uMsg;
    WORD    wParamL;
    WORD    wParamH;
} HARDWAREINPUT, *PHARDWAREINPUT, FAR* LPHARDWAREINPUT;

#define INPUT_MOUSE     0
#define INPUT_KEYBOARD  1
#define INPUT_HARDWARE  2

typedef struct tagINPUT {
    DWORD   type;

    union
    {
        MOUSEINPUT      mi;
        KEYBDINPUT      ki;
        HARDWAREINPUT   hi;
    };
} INPUT, *PINPUT, FAR* LPINPUT;

WINUSERAPI
UINT
WINAPI
SensdasdInput(
    UINT    cInputs,     // number of input in the array
    LPINPUT pInputs,     // array of inputs
    int     cbSize);     // sizeof(INPUT)


With this done I could use it and I tested it with the following code.

INPUT inputevents[2];
KEYBDINPUT keyevent;

keyevent.wVk = VK_UP;
keyevent.dwFlags = 0;
inputevents[0].type = INPUT_KEYBOARD;
inputevents[0].ki = keyevent;

keyevent.wVk = VK_UP;
keyevent.dwFlags = KEYEVENTF_KEYUP;
inputevents[1].type = INPUT_KEYBOARD;
inputevents[1].ki = keyevent;

SendInput(2, &inputevents[0], sizeof(inputevents[0]));


Now I got the follwing errer:

error LNK2001: unresolved external symbol "__declspec(dllimport) unsigned int __stdcall SendInput(unsigned int,struct tagINPUT *,int)" (__imp_?SendInput@@YGIIPAUtagINPUT@@H@Z)


So, Im just wondering how I should do to use SendInput? By the way, I got it to work in Visual Basic on the same computer.
Avatar of mcon1
mcon1

I'm not sure how you have everything structured, I tried it and it worked for me.

Here is what I did.

In my unit1.cpp file in had:
#include "unit1.h"

and in my unit1.h file I had:
#include <stdio.h>
#include <iostream.h>

I didn't include winuser.h
and I commented out the declerations you copied from winuser.h.

I used Borland Builder 5.
Any other info you can add would be helpful!
Avatar of Granis

ASKER

Adjusted points from 50 to 100
Avatar of Granis

ASKER

Ok, here is the complete test app im using:


C++ Source File: SendInput.cpp

#include <windows.h>
#include <stdio.h>
#include "SendInput.h"

int main(int argc, char **argv)
{
      INPUT inputevents[2];
      KEYBDINPUT keyevent;

      keyevent.wVk = VK_UP;
      keyevent.dwFlags = 0;
      inputevents[0].type = INPUT_KEYBOARD;
      inputevents[0].ki = keyevent;

      keyevent.wVk = VK_UP;
      keyevent.dwFlags = KEYEVENTF_KEYUP;
      inputevents[1].type = INPUT_KEYBOARD;
      inputevents[1].ki = keyevent;

      SendInput(2, &inputevents[0], sizeof(inputevents[0]));
}


C++ Header File: SendInput.h

Same as previous post (Noticed that the declaration of SendInput in my post was miss spelled, but in the program its correct.


I include windows.h in which winuser.h  is included.


I use Microsoft Visual C++ 6.0 and im running Windoes 2000 Server.


Is there any more info you need?
if you declare the function SendInput in your file SendInput.h you will need to define the function in the file SendInput.cpp.
If this hasn't been done, you will need to find the implementation file winuser.cpp or perhaps winuser.c and copy that definition into your SendInput.cpp. If you don't have the code for the function, you can compile ok, but the linker can't find where to go for the code. The message "unresolved external symbol" means that the function declaration was ok, but the linker can't find the definition.
I'm sure it would be preferable to use the standard declaration, so maybe you could give some more background on why you can't just use the standard declaration out of winuser.h. Are you sure of spelling and capitalization?
Avatar of Granis

ASKER

Ok, im going to try that out.

Of course i would like to use the standard definition, but if i remove my SendInput.h file i got the following errors:

error C2065: 'INPUT' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'inputevents'
error C2065: 'inputevents' : undeclared identifier
error C2109: subscript requires array or pointer type
error C2065: 'KEYBDINPUT' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'keyevent'
error C2065: 'keyevent' : undeclared identifier
error C2228: left of '.wVk' must have class/struct/union type
error C2228: left of '.dwFlags' must have class/struct/union type
error C2109: subscript requires array or pointer type
error C2228: left of '.type' must have class/struct/union type
error C2065: 'INPUT_KEYBOARD' : undeclared identifier
error C2109: subscript requires array or pointer type
error C2228: left of '.ki' must have class/struct/union type
error C2228: left of '.wVk' must have class/struct/union type
error C2228: left of '.dwFlags' must have class/struct/union type
error C2109: subscript requires array or pointer type
error C2228: left of '.type' must have class/struct/union type
error C2109: subscript requires array or pointer type
error C2228: left of '.ki' must have class/struct/union type
error C2065: 'SendInput' : undeclared identifier    
error C2109: subscript requires array or pointer type
error C2102: '&' requires l-value                    
error C2109: subscript requires array or pointer type


So wometing is wrong here. If i look in the winuser.h the declarations a extracted are in an if clause like follows:

#if (_WIN32_WINNT > 0x0400)
.....
#endif // (_WIN32_WINNT > 0x0400)

I asume this is to check which windows version i have when SendInput just works on Windows 98 and Win NT 4.0 or greater.



actually I don't think you can get the source for SendInput.
I think you will have to link with library user32.lib.
To do that, add it under the link tab in the project settings dialog where it says Object/library modules.
Avatar of Granis

ASKER

Ok, i have already checked this up, user32.lib is included.

The problem seems to be that the SendInput declaration is excluded from my versions of user32.lib and winuser.h, i mean, they are there, but they are not executed. Could maybe new verions of winuser.h and user32.lib help, and where can i get thoose?

I didn't find any winuser.cpp or something like that. If i understand this correctly the declare are instead made in user32.lib, but how do i extract it from that one?
Avatar of Granis

ASKER

Well, im new to this with win32api in C++ so i don't understand this so good.

I now understand that the declarations are not made in user32.lib, but what are made there?
the .lib files contain the source for declarations made in .h files. They are similar to a .dll but statically linked.

ASKER CERTIFIED SOLUTION
Avatar of lthomas
lthomas

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Granis

ASKER

Answer accepted
Avatar of Granis

ASKER

Thanks, this worked.

I ran into the same problem.  I am running Visual C++ 6.0 on Windows XP, but I could not compile any of the SendInput API.  I tried commenting out the OS version check in winuser.h, but that didn't work.  I tried the accepted answer above, and it did not work.  My solution was to copy the API code from winuser.h and paste it into my own header, and link to user32.lib.  Problem solved.  I still don't know why it didn't work in the first place though.  Bizarre.