Reputation: 3891
I used SetWindowHook
to set a low level keyboark hook for instant global hotkeys.
But when I try to use hotkeys for letters such as ';'[],/', it returns incorrect/high value letters. Like when I press comma, it gives me a 1/4th sign.
Here is the callback
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
char letter;
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
letter = (char)vkCode;
// converts letters to capitals
if (char.IsLetter(letter) == true)
{
if ((((ushort)GetKeyState(0x14)) & 0xffff) != 0)
{
letter = char.ToUpper(letter);
if (GetAsyncKeyState(((int)VirtualKeys.Shift)) != 0)
letter = char.ToLower(letter);
}
else if (GetAsyncKeyState(((int)VirtualKeys.Shift)) != 0)
{
letter = char.ToUpper(letter);
}
else
{
letter = char.ToLower(letter);
}
}
logs.Add(letter);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
How can I get punctuation hotkeys without manually comparing every single wrong value?
Upvotes: 1
Views: 252
Reputation: 108810
The first problem is that you're using a keyboard hook to get hotkeys when there is a perfectly fine RegisterHotkey
function.
Then there is the misunderstanding that a key and a character are the same thing. Hotkeys are based on virtual keys, check the Keys
enum for the virtual key values in C#. There is no 1 to 1 mapping between keys and characters. Many keyboard layouts don't have [ key. For example on a German keyboard [
is altgr+8
Upvotes: 2
Reputation: 887547
You need to read the scanCode
rather than the vkCode
from the KBDLLHOOKSTRUCT
structure pointed to by lParam
.
You need to create a managed struct
equivalent to KBDLLHOOKSTRUCT
, then change your callback to take a ref
copy of the struct.
Upvotes: 1