I'm trying to use SendInput()
function. I wrote this code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winuser.h>
#define WIN32_LEAN_AND_MEAN
//...
KEYBDINPUT kbi;
kbi.wVk = 0x31;
kbi.wScan = 0;
kbi.dwFlags = 0;
kbi.time = 0;
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki = kbi;
SendInput(1, &input, sizeof input);
Compiling:
gcc -Wall -o window.exe win32.c -lWs2_32
I get:
win32.c: In function ‘main’:
win32.c:13:2: error: ‘KEYBDINPUT’ undeclared (first use in this function)
win32.c:13:2: note: each undeclared identifier is reported only once for each function it appears in
win32.c:13:13: error: expected ‘;’ before ‘kbi’
win32.c:14:2: error: ‘kbi’ undeclared (first use in this function)
win32.c:20:2: error: ‘INPUT’ undeclared (first use in this function)
win32.c:20:8: error: expected ‘;’ before ‘input’
win32.c:21:2: error: ‘input’ undeclared (first use in this function)
win32.c:21:15: error: ‘INPUT_KEYBOARD’ undeclared (first use in this function)
I have no idea how to fix tihis. According the documentation it's declared in Winuser.h
header. But don't works for me.
#define _WIN32_WINNT 0x0403
#include <windows.h>
Seems this is the magic #define you need somewhere in your project (either explicitly in code, or via compiler command line param -D).
Note that windows.h includes winuser.h, so there's no need to include that, as it's included already for you. Also, the WIN32_LEAN_AND_MEAN define only has any effect if it's included before windows. Details about what it does here; it's not needed or particularly useful these days.
--
So what's going on here? Looking for the definition of KBDINPUT in winuser.h (C:\Cygwin\usr\include\w32api\winuser.h), we see:
#if (_WIN32_WINNT >= 0x0403)
typedef struct tagMOUSEINPUT {
...
} MOUSEINPUT,*PMOUSEINPUT;
typedef struct tagKEYBDINPUT {
...
That's the problem; these only get defined if _WIN32_WINNT is greater than 0x0403.
Those are the files from the cygwin package. Interestingly, the winuser.h from the Microsoft SDK (usually installed in C:\Program Files\Microsoft SDKs\Windows\v7.1\Include\WinUser.h) uses a different condition:
#if (_WIN32_WINNT > 0x0400)
...which explains Jay's suggestion - he's likely looking at the MS files, where 0x0401 would be sufficient here; and also explains why it's not working for you - you're likely using the cygwin ones with a higher version requirement. As to why these two files are different - I've no idea there...