3

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;
}  
0

1 Answer 1

1

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 to GetAsyncKeyState.

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

Sign up to request clarification or add additional context in comments.

7 Comments

GetAsyncKeyState uses the most significant bit to represent the current state of the key: "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."
@MilesBudnek: the "and" here is a logical and I believe. Hence, if they key was not pressed since the last call, the function will always return false no matter the state of the key.
Nope, just did a quick test. It returns 0x8001 right after I press the key, and then 0x8000 until I release it.
@AndyG thanks a lot for pointing me in the right direction. I actually got to do exactly what I wanted from the get go, which is use a toggled state. I replaced it with this bit if(GetKeyState(VK_CAPITAL) == 1 )
@MilesBudnek: Thank you very much for your thoroughness! I've updated the post. I hope you find it more accurate.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.