0

I use globalKeyboardHook to detect certain keyboard keys. The keyboard is a standard English Microsoft 101 keys. For multiple languages, I need all the alphabet (no numerical) and the punctuation (period comma [ ] + = _ - ' ; and some similar. I do not want the control chars to be included.

To filter in the keys I need, I use the char.Isletter || char.isPunctuation. To my surprise, I found out that with the keyboardGlobalHook, the char.IsPunctuation do not return the standard punctuation (period, comma and more). It seems as if the returned keyCodes and keyValues are different with the hook. When running the same char.isPunctuation in a simple test program without the hook, it returns the correct (?) list of punctuation keys as follows:

39 ''':
40 '(':
41 ')':
42 '*':
44 ',':
45 '-':
46 '.':
47 '/':
58 ':':
59 ';':
63 '?':
64 '@':
91 '[':
92 '\':
93 ']':
95 '_':
123 '{':
125 '}':
161 '¡':
171 '«':
173 '-':
183 '·':
187 '»':
191 '¿':

How can I filter only the keys I need, using the built-in char.Is... filters? (I could naturally make a list of all the keys I need, but for that I will need to run the global hook and press each key to determine the returned code).

Auguste
  • 2,007
  • 2
  • 17
  • 25
samtal
  • 131
  • 2
  • 12
  • Such a keyboard hook produces *virtual* key codes. They are the same anywhere in the world. The characters they produce are not, they depend on the keyboard layout that the user selected and the keyboard state, such as whether the Shift/Ctrl/Alt keys are down and any dead keys like AltGr were pressed before. These properties are per-process so it is not generally possible to do this reliably with a global hook. You need a WH_KEYBOARD hook, that's very hard to get going since you can't write one in C#. – Hans Passant Jun 03 '16 at 16:25

1 Answers1

0

Thanks Hans. Based on your answer and my experience, I realized that the virtual key codes do not match the char.Is... methods. I therefore solved the issue by simply relating to each key, as follows: 1. I have built a simple globalKeyBoardHook program that display in a text box the code information of any key:

 public void gkh_KeyDown(object sender, KeyEventArgs e)
    {
  string text = e.KeyValue.ToString() + "," + e.KeyCode.ToString() +","+ (char)(e.KeyValue);
  richTextBox1.AppendText(text + Environment.NewLine);
  File.AppendAllText(@"C:\temp\keys.csv", text + ",\r\n"); //optional log to file
    }

2. I then detected the code for all keys that are relevant to me, and Ored them to my main program filter, in addition to the char.IsLetterOrDigit, as follows:

    public int hookProcess(int code, int wParam, ref keyboardHookStruct  lParam) 
    {
     Keys key = (Keys)lParam.vkCode;            
     int keychar = (int)((char)key);

    if (char.IsLetterOrDigit((char)key) || keychar == 32 || keychar == 186
    || keychar == 188 || keychar == 190 || keychar == 191 ||keychar == 219
    || keychar == 220 || keychar == 221 || keychar == 222 || keychar == 226)

      {
       //Do whatever needed or skip if key is irrelevant
      }

    }
samtal
  • 131
  • 2
  • 12