【问题标题】:Cast IntPtr to CWPSTRUCT将 IntPtr 转换为 CWPSTRUCT
【发布时间】:2012-10-04 09:06:15
【问题描述】:

在我的 c# 项目中,我试图拦截来自另一个程序的鼠标点击,但也只拦截来自某个 hwnd 的鼠标点击……我读过here,我可以使用 lParam 过滤我的消息,但我'还没有成功地将它转换为我实际上可以让 Hwnd 回来的东西。

这就是我设置全局鼠标钩子的方式:

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

然后我在这个函数中捕获消息:

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);
}

然后我像这样制作了 CWPSTRUCT:

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

这是可能出错的部分...我尝试了 2 件事:

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

或者不安全的版本this is where I got it from

CWPSTRUCT* cp = (CWPSTRUCT*)lParam;

使用第一个选项时,hwnd 部分总是为 0,而使用不安全的版本时,我什么也得不到……我真的不知道我在做什么错。任何帮助将不胜感激:)

谢谢

【问题讨论】:

    标签: c# intptr mouse-hook


    【解决方案1】:

    由于您要挂钩 WH_MOUSE_LLlParam 包含指向 MSLLHOOKSTRUCT 而不是 CWPSTRUCT(实际上是 WH_CALLWNDPROC)的指针。

    所以你应该定义以下结构:

    [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;
    }
    

    并将lParam 编组为MSLLHOOKSTRUCT

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

    另外,您应该将wParam 的类型从int 更改为IntPtr,这样它才能在64 位平台上正常工作。

    其他链接:

    【讨论】:

    • 非常感谢!这解决了我的问题。我确实还有 1 个小问题...... UIntPtr dwExtraInfo,它到底包含什么? (与消息相关的附加信息。)因为我认为它可能是我单击的窗口?但我不认为这是因为它也是 0。我现在使用WindowFromPoint 获得了我单击的窗口的句柄,这是正确的方法吗?
    • @VincentC dwExtraInfo 似乎是对特定于应用程序的额外信息的引用。
    • @VincentC 是的,你可以使用WindowFromPoint 来获取hwnd。尽管为WH_MOUSEWH_CALLWNDPROC 创建一个全局挂钩会更好。你可以在这里阅读:Using Window Messages to Implement Global System Hooks in C#
    猜你喜欢
    • 2012-12-29
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2013-08-12
    • 2010-09-07
    • 2016-12-07
    相关资源
    最近更新 更多