Reputation: 1835
I am using a class i got from this blog: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
This function get the key code for a single key, i wanted to alter it so i can catch ctrl+C so i altered the above function as follows:
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if ((Keys)(vkCode) == Keys.C && (Control.ModifierKeys == Keys.Control))
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
The problem is Control.ModifierKeys always returns NONE, i googled too much with any results, i want to note that i am using this code in class in a separate module in the solution. What am i doing here, please provide a solution.
Upvotes: 0
Views: 994
Reputation: 941942
Yes, this will go wrong in general but especially when your program does itself not have a GUI or uses a hidden window. Windows maintains keyboard state for each individual process, it is updated when a program receives a keyboard message. This is necessary because key strokes are stored in the message queue and get retrieved by the program later, sometimes much later. The problem with a keyboard hook is that it was another process that got the message, not yours. You've still got the stale keyboard state.
To make it truly reliable, you'll need to know the keyboard state of the other process. But that's not something you can get to, the GetKeyboardState() function only allows permitting retrieving your own state. This in general makes translating key strokes to typing keys very difficult. A WH_KEYBOARD hook is a much better solution but you cannot write such a hook in C#.
A workaround is to track the state of the Control key yourself. Or by pinvoking GetAsyncKeyState() to check the actual unbuffered state of the Control key.
Upvotes: 1
Reputation: 109712
That won't work for you!
The implementation of Control.ModifierKeys just calls the Windows API function GetKeyState() three times, with parameters 0x10, 0x11 and 0x12 in turn, and ors the results appropriately.
But the state is tied to which message from the message queue is being processed.
I think you need to use PInvoke to call the Windows API function GetAsyncKeyState() instead.
Upvotes: 0