8

I would like to have a boolean event toggle when a key is pressed. Specifically, the 's' key. I have been pointed to the function GetKeyState(), which supposedly works under the Win32 API. I understand the ASCII code for the letter 's' is 115, and so my code is as follows:

if (GetKeyState(115) == 1)
{
<EVENT>
}

However, this does not work. Why? Here is the MSDN reference: http://msdn.microsoft.com/en-us/library/ms646301%28v=vs.85%29.aspx ... "If the low-order bit is 1, the key is toggled"

CaptainProg
  • 5,610
  • 23
  • 71
  • 116
  • Just compare it to zero -> See : [How do I get the high- and low-order bits of a SHORT?](https://stackoverflow.com/questions/5302456/how-do-i-get-the-high-and-low-order-bits-of-a-short) – Paul Sumpner Sep 10 '19 at 13:38

5 Answers5

21

From what I understand you need to do:

if( GetKeyState(115) & 0x8000 )
{
    <EVENT>
}

The highest bit tells if key is pressed. The lowest tells if key is toggled (like, if caps lock is turned on).

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
  • 1
    Thanks, I've tried this but still my event doesn't occur when I press 's'. The program compiles just fine though. I'm using Win32 API, am I missing anything else? The compiler obviously recognises the function... – CaptainProg Jun 13 '11 at 14:59
  • Maybe you want [GetAsyncKeyState](http://msdn.microsoft.com/en-us/library/ms646293). `GetKeyState` has to be called in response to keyboard event. – Piotr Praszmo Jun 13 '11 at 15:14
  • 2
    The virtual key codes for the letter keys correspond to the ASCII codes of the upper case letters. And you can even use a `char` instead of the `int` which makes the code more readable. So try `GetKeyState('S')` – kiw Oct 15 '13 at 07:41
15

Since SHORT is signed, high-order bit equals sign bit.

Therefore to test if a given key is pressed, simply test if the value returned by GetKeyState() is negative:

if (GetKeyState('S') < 0) {
    // The S key is down.
} else {
    // The S key is up.
}

Besides, 115 is ASCII code for 's'. I believe, you should use capital case 83 to test the 'S' key.

Simon Rozman
  • 308
  • 3
  • 8
-3

I use a global variable bool altgr

Example:

void Editor::HandleKey(char car) {

    bool shift = false;
    //bool altgr = false;
    bool printable = false;

    if (car == 27) SendMessage(hwnd, WM_DESTROY, 0, 0);

    if ((GetKeyState(VK_CAPITAL) & 0x0001) == 1) shift = true;
    if ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000) shift = true;
    // if(GetKeyState(VK_RMENU) & 0x80000000 == 0x80000000) altgr = true;
    if (car == 18) altgr = true; 
Scott Smith
  • 3,900
  • 2
  • 31
  • 63
-3

Sometimes you want to use a combination of keys.

To avoid the situations when a combination of keys (eg: VK_SHIFT && VK_LEFT) satisfies two conditions:

std::cout << "Shift RIGHT pressed" << std::endl;
std::cout << "LEFT key pressed" << std::endl;

just use Sleep(...); and GetAsyncKeyState(VK_...)

GetKeyState() vs. GetAsyncKeyState() vs. getch()?

#include <windows.h>  

    ...

    while (1)
    {
        if ((GetKeyState(VK_SHIFT) & 0x8000) && (GetAsyncKeyState(VK_LEFT) & 0x8000))
        {
            Sleep(200);
            std::cout << "Shift LEFT pressed" << std::endl;
        }

        if ((GetKeyState(VK_SHIFT) & 0x8000) && (GetAsyncKeyState(VK_RIGHT) & 0x8000))
        {
            Sleep(200);
            std::cout << "Shift RIGHT pressed" << std::endl;
        }

        if (GetAsyncKeyState(VK_RIGHT))
        {
            std::cout << "RIGHT key pressed" << std::endl;
        }

        if (GetAsyncKeyState(VK_LEFT))
        {
            std::cout << "LEFT key pressed" << std::endl;
        }
   }
-11

Bit late for this but the high order bit is 0x80000000 not 0x8000, change this and it will work fine.

The other bit - useful for nothing - it acts as if you pressed CAPS LOCK when you pressed LSHIFT.

Laurie
  • 1
  • 1
  • 7
    As stated in [GetKeyState MSDN reference](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx), the return value is a `SHORT` (16 bits), not a 32 bit value (in other words, `0x80000000` is not valid). – EDDY74 Jan 13 '15 at 14:12