Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everyone. I wrote a simple console application in C# that records typed keys and prints them on screen. Here's the code:

using System;
using static System.Threading.Thread;
using System.Runtime.InteropServices;
using System.Windows.Input;

namespace Demo_2
{
    class Program
    {
        [DllImport("User32.dll")]
        private static extern short GetAsyncKeyState(int key);

        [STAThread]
        static void Main()
        {
            while (true)
            {
                Sleep(5);

                for (var key = 0; key < 255; key++)
                {
                    if (GetAsyncKeyState(key) == -32767)
                    {
                        Console.Write(PrintKey(key));
                    }
                }
            }
        }

        private static string PrintKey(int key)
        {
            bool shift = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
            bool iscap = Keyboard.IsKeyToggled(Key.CapsLock) ^ shift;
            bool isnum = Keyboard.IsKeyToggled(Key.NumLock);

            string buffer = String.Empty;

            switch (key)
            {
                case 13:
                    buffer = "\n";
                    break;
                case 32:
                    buffer = " ";
                    break;
                case 48:
                    buffer = shift ? ")" : "0";
                    break;
                case 49:
                    buffer = shift ? "!" : "1";
                    break;
                case 50:
                    buffer = shift ? "@" : "2";
                    break;
                case 51:
                    buffer = shift ? "#" : "3";
                    break;
                case 52:
                    buffer = shift ? "$" : "4";
                    break;
                case 53:
                    buffer = shift ? "%" : "5";
                    break;
                case 54:
                    buffer = shift ? "^" : "6";
                    break;
                case 55:
                    buffer = shift ? "&" : "7";
                    break;
                case 56:
                    buffer = shift ? "*" : "8";
                    break;
                case 57:
                    buffer = shift ? "(" : "9";
                    break;
                case 186:
                    buffer = shift ? ":" : ";";
                    break;
                case 187:
                    buffer = shift ? "+" : "=";
                    break;
                case 188:
                    buffer = shift ? "<" : ",";
                    break;
                case 189:
                    buffer = shift ? "_" : "-";
                    break;
                case 190:
                    buffer = shift ? ">" : ".";
                    break;
                case 191:
                    buffer = shift ? "?" : @"/";
                    break;
                case 192:
                    buffer = shift ? "~" : "`";
                    break;
                case 65:
                    buffer = iscap ? "A" : "a";
                    break;
                case 66:
                    buffer = iscap ? "B" : "b";
                    break;
                case 67:
                    buffer = iscap ? "C" : "c";
                    break;
                case 68:
                    buffer = iscap ? "D" : "d";
                    break;
                case 69:
                    buffer = iscap ? "E" : "e";
                    break;
                case 70:
                    buffer = iscap ? "F" : "f";
                    break;
                case 71:
                    buffer = iscap ? "G" : "g";
                    break;
                case 72:
                    buffer = iscap ? "H" : "h";
                    break;
                case 73:
                    buffer = iscap ? "I" : "i";
                    break;
                case 74:
                    buffer = iscap ? "J" : "j";
                    break;
                case 75:
                    buffer = iscap ? "K" : "k";
                    break;
                case 76:
                    buffer = iscap ? "L" : "l";
                    break;
                case 77:
                    buffer = iscap ? "M" : "m";
                    break;
                case 78:
                    buffer = iscap ? "N" : "n";
                    break;
                case 79:
                    buffer = iscap ? "O" : "o";
                    break;
                case 80:
                    buffer = iscap ? "P" : "p";
                    break;
                case 81:
                    buffer = iscap ? "Q" : "q";
                    break;
                case 82:
                    buffer = iscap ? "R" : "r";
                    break;
                case 83:
                    buffer = iscap ? "S" : "s";
                    break;
                case 84:
                    buffer = iscap ? "T" : "t";
                    break;
                case 85:
                    buffer = iscap ? "U" : "u";
                    break;
                case 86:
                    buffer = iscap ? "V" : "v";
                    break;
                case 87:
                    buffer = iscap ? "W" : "w";
                    break;
                case 88:
                    buffer = iscap ? "X" : "x";
                    break;
                case 89:
                    buffer = iscap ? "Y" : "y";
                    break;
                case 90:
                    buffer = iscap ? "Z" : "z";
                    break;
                case 96:
                    buffer = isnum ? "0" : "";
                    break;
                case 97:
                    buffer = isnum ? "1" : "";
                    break;
                case 98:
                    buffer = isnum ? "2" : "";
                    break;
                case 99:
                    buffer = isnum ? "3" : "";
                    break;
                case 100:
                    buffer = isnum ? "4" : "";
                    break;
                case 101:
                    buffer = isnum ? "5" : "";
                    break;
                case 102:
                    buffer = isnum ? "6" : "";
                    break;
                case 103:
                    buffer = isnum ? "7" : "";
                    break;
                case 104:
                    buffer = isnum ? "8" : "";
                    break;
                case 105:
                    buffer = isnum ? "9" : "";
                    break;
                case 106:
                    buffer = "*";
                    break;
                case 107:
                    buffer = "+";
                    break;
                case 109:
                    buffer = "-";
                    break;
                case 110:
                    buffer = isnum ? "." : "";
                    break;
                case 111:
                    buffer = @"/";
                    break;
            }
            return buffer;
        }
    }
}


All keys are included except for those in range 219-222. When I run the application and start typing some random text in Notepad,everything seems fine. However,whenever I start typing really fast,keystrokes either get permuted or dropped (for example "that" becomes "taht" or "tht",etc.) I saw two people complaining about the same issue (Both used GetAsyncKeyState() function) but no one gave them proper explanation. I would really appreceiate if someone could explain me what's the issue and if it can be solved with simple code modification. Thanks.

What I have tried:

Besides -32767,I tried using different states,but everything seemed even worse after it.
Posted
Updated 2-May-21 9:05am

1 solution

Yeah, what you're doing is polling for the state of 255 keys, one at a time. That's extremely inefficient and slow.

You would be much better off implementing a global keyboard hook[^]. That means your code is celled every time a key is made or broken.

The polling code you wrote will never run fast enough to keep pace with a fast typist. There will always be someone who can type faster.
 
Share this answer
 
Comments
NickNs1991 2-May-21 15:58pm    
Thanks for answer.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900