There is a difference between keystrokes and the characters that they generate.
At the lowest level, you can poll the status of the keyboard using GetKeyboardState . This often happens as mallogging malware does, because it requires the least privileges and sees everything no matter where the focus is. The problem with this approach (besides the need for constant polling) is that you need to combine the keyboard state into keystrokes and then keystrokes into a character stream. You need to know how the keyboard is displayed, you save the state of the shift keys, control keys, Alt keys, etc. You should be aware of auto-repeat, dead keys, and possibly other complications.
If you have privileges, you can set the hook for the keyboard, as Jens pointed out in his answer.
If you have focus and you are a console application, you use one of the functions to read from standard input. On Windows, it is difficult to get true Unicode input. Usually you get the so-called ANSI characters that correspond to the current code page of the console window. If you know the code page, you can use MultiByteToWideChar to convert single or multi-byte input to UTF-16 (which Windows documentation calls Unicode). From there, you can convert it to UTF-8 ( WideCharToMultiByte ) or whatever other Unicode encoding you want.
If you have focus and you are a GUI, you can see the keystrokes of WM_KEYDOWN (and friends). You can also get fully resolved UTF-16 characters with WM_CHAR (or UTF-32 from WM_UNICHAR ). If you need UTF-8, you will need to do the conversion.
source share