In order to understand what WM_CHAR, WM_KEYDOWN, and WM_SYSKEYDOWN do, you could write a simple program that writes information to the screen when those "cases" are triggered. For example, when Ctrl C is pushed my program shows something like this (events scroll up - the bottom has column descriptions):
WM_KEYDOWN | 0x11 |00000000001D0001
WM_KEYDOWN |0x43 'C'|00000000002E0001
WM_CHAR |0x03 |00000000002E0001
--------------------------------------------------------------
Where from | wParm | lParam
As you can see from this, the wParm parameter has useful information about the events. The Ctrl key produces 0x11 in WM_KEYDOWN, then the 'C' key produces 0x43 in WM_KEYDOWN, and finally the combination of the two keys produces the expected 0x03 in WM_CHAR (just don't hold the Ctrl key for too long or it will repeat). I was interested in creating "characters" using two digit hexadecimal so I used the key program to come up with a concept. The concept I came up with is to push and release the Alt key followed by pushing two hex characters. For example, Alt 31 produces the numeric character 1 and Alt ff produces a color coded 'F'.
Note: If you have the book "Programming Windows Fifth Edition" by Charles Petzold, he has already developed programs that give key information similar to above when keys are pushed (see Chapter 6 "KeyView1" and "KeyView2" - they are also on the book's CD).