1

I have written a following piece of code that displays all keystrokes. What I want know is that if I press combination keys like Ctrl+A, Alt+O or Ctrl+Delete or Ctrl+Alt+Delete these keys also gets displayed on console. What should be the approach?

Another thing that just popped into mind is that if somebody is holding a key and keep pressing other key how this behavior could be captured here?

[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Int32 i);

for (Int32 i = 0; i < 255; i++)
{
    int keyState = GetAsyncKeyState(i);
    if (keyState == 1 || keyState == -32767)
    {
        Console.WriteLine((Keys)i);
        break;
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Naseer
  • 4,041
  • 9
  • 36
  • 72
  • 3
    Did you [read the documentation for `GetAsyncKeyState`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx)? – Uwe Keim Oct 07 '14 at 20:11
  • Yes uwe I read that but it was cryptic for goof like me.Actually win32 API looks very scary to me.I planned to read that again and again and then decided to throw my code to garbage but then I thought there is stackoverflow which could help me. – Naseer Oct 07 '14 at 20:12
  • 2
    @khan, then you have to develop the background and skills required to understand the documentation, otherwise you don't have a chance of understanding what actual code does. – Frédéric Hamidi Oct 07 '14 at 20:16
  • I am not sure what you are trying to do? Are you trying the read keyboard state from a background application? – Black Frog Oct 07 '14 at 20:25
  • @Black Frog No, just a console application. – Naseer Oct 07 '14 at 20:28

2 Answers2

3

I believe you are looking for GetKeyboardState function. I will give you status of all virtual keys in one call. The GetAsyncKeyState function is better used to check if the user pressed a key or not.

As an exercise, I wrote the following to demonstrate the GetAsyncKeyState API call:

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace s26244308
{
    class Program
    {
        static void Main(string[] args)
        {
            bool keepGoing = true;

            while (keepGoing)
            {
                int wasItPressed = SysWin32.GetAsyncKeyState(SysWin32.VK_ESCAPE);
                if (wasItPressed != 0)
                {
                    keepGoing = false;  // stop
                    continue;
                }

                // for this sample: just loop a few letters
                for (int x = 0x41; x <= 0x4A; x++)
                {
                    int letterPressed = SysWin32.GetAsyncKeyState(x);
                    if (letterPressed != 0)
                    {
                        // now check for a few other keys
                        int shiftAction = SysWin32.GetAsyncKeyState(SysWin32.VK_SHIFT);
                        int ctrlAction = SysWin32.GetAsyncKeyState(SysWin32.VK_CONTROL);
                        int altAction = SysWin32.GetAsyncKeyState(SysWin32.VK_MENU);

                        // format my output
                        string letter = string.Format("Letter: {0} ({1})", Convert.ToChar(x), KeyAction(letterPressed));
                        string shift = string.Format("Shift: {0}", KeyAction(shiftAction));
                        string ctrl = string.Format("Control: {0}", KeyAction(ctrlAction));
                        string alt = string.Format("Alt: {0}", KeyAction(altAction));

                        Console.WriteLine("{0,-20}{1,-18}{2,-18}{3,-18}", letter, shift, ctrl, alt);
                        break;
                    }
                }
                Thread.Sleep(10);
            }

            Console.WriteLine("-- Press Any Key to Continue --");
            Console.ReadLine();
        }

        private static string KeyAction(int pressed)
        {
            if (pressed == 0)
                return "Up";

            // check LSB
            if (IsBitSet(pressed, 0))
                return "Pressed";

            // checked MSB
            if (IsBitSet(pressed, 15))
                return "Down";

            return Convert.ToString(pressed, 2);
        }
        private static bool IsBitSet(int b, int pos)
        {
            return (b & (1 << pos)) != 0;
        }
    }

    class SysWin32
    {
        public const int VK_ESCAPE = 0x1B;
        public const int VK_SHIFT = 0x10;
        public const int VK_CONTROL = 0x11;
        public const int VK_MENU = 0x12;

        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Int32 i);
    }

}

here is the console output: Console Output

Black Frog
  • 11,595
  • 1
  • 35
  • 66
  • I appreciate you did this exercise for me. – Naseer Oct 08 '14 at 08:40
  • a thing that irritates me that why we need a loop for getAsync since it accepts a keyboard input,I mean how does it correctly displays my input key at specific iteration of for loop. – Naseer Oct 08 '14 at 08:43
  • Because of the thread sleeps. If a key is pressed when the thread is sleeping, the thread can only tell you the action afterwards. And you cannot have the thread listening all the time. It sounds more like you need to hook into the Windows Message Pump to get all keyboard messages. Check out the accepted answer from [C++ console keyboard events](http://stackoverflow.com/questions/2067893/c-console-keyboard-events). – Black Frog Oct 08 '14 at 12:46
1

I think I understand what you are asking. You want a way to check the key combinations that a user presses. I have attempted what you are looking for without using GetAsyncKeyState().

Here is the KeyDown Event action that I made:

prevKey = currentKey;
currentKey = e.KeyCode; 

if (prevKey == Keys.ControlKey && currentKey == Keys.Menu)
{
   // Some action
}
else
   // Some other action

You have the ability to monitor key combinations that the user presses and correlate an action to a certain combination. The above code shows if a user was to press CTRL + ALT in that sequence.

The reason that KeyDown event is better is because you capture the key value right when it is pressed.

Ckrempp
  • 324
  • 2
  • 9