Question

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

Was it helpful?

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:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top