2
votes

I am using a global keyboard hook (WH_KEYBOARD_LL) and sending the keys to a browser handle. I am able to get a single key pressed by the user but not able to get the combination of keys pressed(such as shift+left for selecting text).The code goes below...

private IntPtr ProcessKey(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0
        && wParam == (IntPtr)WM_KEY_EVENT.WM_KEYDOWN
        || wParam == (IntPtr)WM_KEY_EVENT.WM_SYSKEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);
        int vkCode1 = Marshal.ReadInt32(wParam);//here I am getting runtime
        //error as Attempted to read or write protected memory.
        //This is often an indication that other memory is corrupt. 

        SafeNativeMethods.PostMessage(m_browserHandle,(uint)WM_KEY_EVENT.WM_KEYDOWN,  
            Convert.ToInt32((System.Windows.Forms.Keys)vkCode),
            Convert.ToInt32((System.Windows.Forms.Keys)vkCode1));
    }

    return SafeNativeMethods.CallNextHookEx(_hookID, nCode, wParam, lParam);
}

[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

public static class WM_KEY_EVENT
{
    public static int WM_KEYDOWN = 0x0100;
    public static int WM_SYSKEYDOWN = 0x0104;
    public static int WM_KEYUP=0x0101;
    public static int WM_SYSKEYUP=0x0105;
};

I read some where that we can get the combination of key press by using wParam, which gives error as shown in the code above. Please suggest how to avoid that error or some alternative way to do it.

1
What's with all the empty lines?configurator
Possible duplicate of Simulating Key Press c#Deniz

1 Answers

1
votes

Your code has some errors in it. You're treating wParam as a pointer (since you're calling ReadInt32 with it), but according to the documentation it contains the window message.

lParam you should derefernece (using Marshal.PtrToStructure) to a KBDLLHOOKSTRUCT, it contains the key code and modifier key state.

And I don't see the point in casting vkCode to a System.Windows.Fórms.Keys value, and then right back to an int again.