Search code examples
c#intptrmouse-hook

Cast IntPtr to CWPSTRUCT


In my c# project I’m trying to intercept mouse clicks from another program, but only the ones that come from a certain hwnd as well… I’ve read here that I can filter my messages using the lParam but I’ve not succeeded to cast it to something I can actually get Hwnd’s back from.

This is how I set up the global mouse hook:

SetWindowsHookEx(WH_MOUSE_LL, s_MouseDelegate, IntPtr.Zero, 0);

I then catch the messages in this function:

private static int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
    if (nCode >= 0)
    {
          switch (wParam)
          {
               case WM_LBUTTONDOWN:
                    mouseDown = true;
                    mouseUp = false;
                    break;
               case WM_LBUTTONUP:
                    mouseUp = true;
                    mouseDown = false;
                    break;
          }
     }
     return CallNextHookEx(s_MouseHookHandle, nCode, wParam, lParam);
}

I then made the CWPSTRUCT like this:

[StructLayout(LayoutKind.Sequential)]
public struct CWPSTRUCT
{
    public IntPtr lparam;
    public IntPtr wparam;
    public int message;
    public IntPtr hwnd;
}

And here's the part where it probably goes wrong...I’ve tried 2 things:

CWPSTRUCT cwp = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT));

Or the unsafe version this is where I got it from:

CWPSTRUCT* cp = (CWPSTRUCT*)lParam;

When using the first option I always get 0 for the hwnd part and with the unsafe version I just get nothing... I don’t really know what I’m doing wrong here. Any help would be appreciated :)

Thanks


Solution

  • Since you're hooking WH_MOUSE_LL, lParam contains pointer to MSLLHOOKSTRUCT instead of CWPSTRUCT (which is actually for WH_CALLWNDPROC).

    So you should define the following structures:

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public int mouseData;
        public int flags;
        public int time;
        public UIntPtr dwExtraInfo;
    }
    

    And marshal lParam to MSLLHOOKSTRUCT:

    MSLLHOOKSTRUCT mouseLowLevelHook = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam,
        typeof(MSLLHOOKSTRUCT));
    

    Also, you should change wParam's type from int to IntPtr, so it will work properly on 64-bit platforms.

    Additional links: