I am doing a small project to issue keyboard messages based on the position of a joystick.
The keyboard messages are simulated using SendInput().
Individual keys work properly. My problem is with simulating a key that is held down for a long period. If I use SendInput at every pass of the loop, it is like pressing the key multiple times.
I read on msdn that there is a field with flags to indicate the key's previous state, and other flags.
How do you make modifications to such a field? from where do you get access to it?
UPDATE
Here is the code for the positive X axis:
#include<Windows.h>
#include<iostream>
using namespace std;
#define mid 32767
#define trig 1804
#define reset 1475
// Virtual codes
#define XU 0x44 //D
#define XL 0x41 //A
#define YU 0x53 //S
#define YL 0x57 //W
#define ZU 0x51 //Q
#define ZL 0x45 //E
// Scan codes
#define sXU 0x20 //D
#define sXL 0x1E //A
#define sYU 0x1F //S
#define sYL 0x11 //W
#define sZU 0x10 //Q
#define sZL 0x12 //E
int main()
{
UINT result;
JOYINFO pos;
INPUT xi, yi, zi;
int i = 0;
int state[6] = { 0,0,0,0,0,0 };
int uu = mid + trig;
int ul = mid + reset;
int ll = mid - trig;
int lu = mid - reset;
xi.type = INPUT_KEYBOARD;
yi.type = INPUT_KEYBOARD;
zi.type = INPUT_KEYBOARD;
while (1)
{
result = joyGetPos(i, &pos);
if (result != JOYERR_NOERROR) // Check to which ID is the joystick assigned
{
cout << "JoyID " << i << " returned an error. Trying the next one." << endl;
i++;
if (i > 15)
{
cout << "Reached the maximum allowed attempts. Exiting." << endl;
return 1;
}
}
else // start simulating key preses based on the joystick’s position
{
//-----------------------------------------------------------------
//
// X-axis positive
//
//-----------------------------------------------------------------
if (pos.wXpos > uu)
{
if (state[0] == 1) // Second pass of the loop, re-issue the same key with “previous state” flag as 1
{
xi.ki.wVk = XU;
xi.ki.wScan = sXU;
xi.ki.dwFlags = KEYEVENTF_SCANCODE;
xi.ki.dwExtraInfo = 0x40000000;
SendInput(1, &xi, sizeof(INPUT));
state[0] = 1;
}
if (state[0] == 0) // First pass of the loop, issue the key
{
xi.ki.wVk = XU;
xi.ki.wScan = sXU;
xi.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &xi, sizeof(INPUT));
state[0] = 1;
}
}
if (pos.wXpos < ul && state[0] != 0) // When the joystick returns to the centre, simulate a key up.
{
xi.ki.wVk = XU;
xi.ki.wScan = sXU;
xi.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
//xi.ki.dwExtraInfo = 0x00000000;
SendInput(1, &xi, sizeof(INPUT));
state[0] = 0;
}
Sleep(15);
}
}
return 0;
}
If you try this out you will see that the key is issued only twice. If I modify the condition to re-issue the key at every pass, you will see that it is not like a keyboard's autorepeat.
I think the issue resides with the flags dwExtraInfo. At present I am over-riding whatever there is because I do not know how to read the existing state, given that I do not pass any lparam to any window. Do you have any ideas?
Thanks.