Reputation: 33
I am trying to get a small app that will continuously simulate UP (↑ arrow key) while another key is pressed, in my case Right CTRL.
The code I wrote however, will only send one UP for each press - and while I keep Right CTRL pressed, it will only send one UP and stop.
I want to mention that this code is built entirely from documentation I found online, I have never written anything in C++ ever before, or any other language so any suggestions would greatly help me. I initially tried doing this while CAPS LOCK was active, but I found that getting the key state (on/off) did not work for me at all, no matter what I tried.
int main()
{
// This structure will be used to create the keyboard
// input event.
INPUT ip;
// Pause for 1 seconds.
Sleep(1000);
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
while(1){
if(GetAsyncKeyState(VK_RCONTROL))
{
// Press the "UP arrow" key
ip.ki.wVk = 0x26; // virtual-key code for the "UP arrow" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
Sleep(50);
// Release the "UP arrow" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
Sleep(50);
}
}
// Exit normally
return 0;
}
Upvotes: 3
Views: 2257
Reputation: 41220
GetAsyncKeyState
does not return a boolean about whether the key is up or down, but rather a SHORT
(a 16 bit integer, usually literally short
)
If the function succeeds, the return value specifies whether the key was pressed since the last call to
GetAsyncKeyState
, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call toGetAsyncKeyState
.
So what does this mean? The "most significant bit" in hardware is implementation defined (Which end of a bit field is the most significant bit?), but we can treat everything as if the "leftmost" bit is significant (1000 versus 0001).
So we can test for keydown with a bitmask.
I've written a small demo program to help you visualize all this:
std::cout << "number of bytes in a short: " << sizeof(short) << std::endl;
short i = 0;
i = 1 << (sizeof(short)*8-1); // use bit shifting to set most significant bit
std::cout << "Initial value of i: " << i << std::endl;
std::cout << "Initial value of i as hex: " << std::hex << i << std::endl;
std::cout << "Is most significant bit set?\n";
short bitmask = 0x8000;
std::cout << std::boolalpha << ((bitmask & i) != 0) << std::endl;
std::cout << "Unsetting MSB\n";
i = 0x0000;
std::cout << "Is most significant bit set?\n";
std::cout << std::boolalpha << ((bitmask & i) != 0) << std::endl;
This demo shows how you can apply a bitmask to a short to ask if the most significant bit is set.
GetAsyncKeyState
gives you the additional ability to check if the key was pressed since last check. For a simpler call, check out GetKeyState
Upvotes: 1