0

I would like to check if the user will make a kepress again after the first one to implement a pause function in a while cycle. The console window is not on focus so I can't use Console.Read()

while (true)
        {
            if (GetAsyncKeyState(0x21) != 0) 
                break;  //work just fine, if ESC press it exit while
            if (GetAsyncKeyState(0x05) != 0)
            {
                sw.Start();
                while (sw.ElapsedMilliseconds < 2000)
                {
                    // if side mouse button is press, it wait 2sec, work just fine
                }
                sw.Reset();
            }
            if (GetAsyncKeyState(0x42) != 0)
            {

                while (GetAsyncKeyState(0x42) == 0)
                {

                   // wait the second B pressing to resume  but it dosen't work

                }
             
            }

  main_function();

}

This code seems to not work, I check GetAsyncKeyState with writeline and it seems that it get the keypressed state for few ms so the pause cicle will end. I seems that in console c# I can't use ad hoc functions that c# have for forms to check it.

Thanks!

ItalianOne
  • 221
  • 1
  • 2
  • 8
  • What keypress(es) are you looking for? Do you want to know if they pressed it multiple times?...or held it down? Any reason for not using [Console.Read()](https://learn.microsoft.com/en-us/dotnet/api/system.console.read?view=netcore-3.1) in a loop? Give more detail about what is supposed to happen here. – Idle_Mind Jun 25 '20 at 14:01
  • I want to just pause the main while cycle if someone press B and resume it when they press it again so at the start of the while cycle I just check if the B is pressed (0x42) and if if pressed again. The first two check work just fine. – ItalianOne Jun 25 '20 at 14:13
  • See if this [previous SO answer](https://stackoverflow.com/a/46014022/2330053) would work for you. Technically it's a WinForms app that never displays a form, but it'd allow you to trap keypresses. A similar technique can be used to trap the mouse with WH_MOUSE_LL. – Idle_Mind Jun 25 '20 at 15:04

1 Answers1

0

The solution is:

    // if pressed the first time
    if (GetAsyncKeyState('B'))
    {
        //if previously detected and still held down
        while (!((GetAsyncKeyState('B')) & 0b1000'0000'0001)) 
        {
            //wait in here
        }

        //if key not pressed
        while (!GetAsyncKeyState('B')) 
        {
            //wait in here
        }

        //if you get here, B was pressed, released and pressed again
    }

I don't recommend using GetASyncKeyState for anything but quick and simple Proof of Concepts due to the remarks you will read below.

From MSDN:

Return value Type: 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.

Important remarks:

Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59