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@@YGIIPAU tagINPUT@@ 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.
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@@YGIIPAU
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.
ASKER
Adjusted points from 50 to 100
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?
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.
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?
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.
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.
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.
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?
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?
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?
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Answer accepted
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.
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!