-2

How can I detect if the user is holding down the Space key in C#?

In C++ you would add & 0x8000 as so:

while (true)
{
    if (GetAsyncKeyState(VK_SPACE) & 0x8000)
    {
        std::cout << "User is holding Space!";
    }
}

I've tried to do the same in C# but didn't get far:

[DllImport("user32.dll")]
public static extern short GetAsyncKeyState(Keys key);

while (true)
{
    if (GetAsyncKeyState(Keys.Space) & 0x8000)
    {
        Console.WriteLine("User is holding Space!");
    }
}

What am I doing wrong and how can I detect if the user is holding down spacebar?

Josie
  • 79
  • 8
  • You might want to check other questions like https://stackoverflow.com/questions/22837510/c-sharp-need-if-statement-to-check-for-space-and-arrow-keys-pressed or https://stackoverflow.com/questions/18874380/how-to-capture-the-spacebar-press-event-using-keyeventhandler – Progman Nov 14 '20 at 23:42
  • 1
    Why don't you use: `if (Keyboard.IsKeyDown(Key.Space)) {}` – Julian Nov 14 '20 at 23:51

3 Answers3

4

With a simple console application it works (except the IF condition where you need to check the value, c# is not able to cast number values to bool condition):

class Program
{
    [DllImport("user32.dll")]
    public static extern short GetAsyncKeyState(int key);

    static void Main(string[] args)
    {

        while (true)
        {
            if ((GetAsyncKeyState(32) & 0x8000) > 0)
            {
                Console.WriteLine("User is holding Space!");
            }
        }
    }
}

If you want to use it on a windows form then you should do it on a background thread to not freeze the application with it and store it in a property or fire up an event back to main thread, it depends on the use-case.

An example to use it in WinForms

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    public static extern short GetAsyncKeyState(int key);

    bool spaceIsPressed = false;
    Thread t = null;

    public Form1()
    {
        InitializeComponent();
        t = new Thread(CheckKey);
        t.Start();
    }


    public void CheckKey()
    {
        try
        {
            while (true)
            {
                if ((GetAsyncKeyState(32) & 0x8000) > 0)
                {
                    spaceIsPressed = true;
                }
                else
                {
                    if (spaceIsPressed)
                        spaceIsPressed = false;
                }
                Thread.Sleep(200);
            }
        }
        catch (ThreadInterruptedException ex) { }
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (t != null)
        {
            t.Interrupt();
            t = null;
        }
    }
}
0

In C# you can do it in a similar way as you did it in C++, but the button code will be different.

Answer:

In C# we use Virtual-Key Codes. For every button there is a code. For spacebar it's 0x20

The whole list you can find on Microsoft's page:

https://learn.microsoft.com/pl-pl/windows/win32/inputdev/virtual-key-codes?redirectedfrom=MSDN

FilipA
  • 526
  • 3
  • 10
0

you could also check:

while (true)
 {
     if (Keyboard.IsKeyDown(Key.Space))
     {
         Console.WriteLine("User is holding Space!");
     }
 }

but you could also register to the KeyDown\Up events:

KeyDown += Form2_KeyDown;
KeyUp += Form2_KeyUp;

and then check if the key is space.. that way you dont have to loop in the background:

    private void Form2_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (!Keyboard.IsKeyDown(Key.Space))
        {
            spaceKeyDown = false;
        }
    }

    private void Form2_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            spaceKeyDown = true;
        }
    }
audzzy
  • 721
  • 1
  • 4
  • 12