gpt4 book ai didi

c# - 如何在托管代码中正确翻译 WH_MOUSE lparam

转载 作者:搜寻专家 更新时间:2023-10-31 02:19:21 26 4
gpt4 key购买 nike

我已经设置了一个 WH_MOUSE 钩子(Hook),一切正常,除了我无法获得传递给我的 HOOKPROC 函数在 C# 中正确翻译。

我的项目由两部分组成,C++ 中的非托管部分执行 Hook 和过滤并通知我的托管代码。

问题是我得到的数据不正确,例如转换 lparam 后奇怪的 X 和 Y 坐标。 X 大多数时候是 0,而 Y 大多数时候是正确的,然后每隔一次点击我得到一个值,比如 X 的 198437245 和 Y 的 -1 等。

请注意,我已经确认了以下内容:

  • lparam 的值已正确传递到我的 C# 代码(通过托管和非托管部分上的断点进行验证),例如当发生鼠标事件时,它们都是 2420528
  • 非托管代码与托管代码处于相同的上下文中,即相同的地址空间。
  • lparam 的值是正确的,因为我可以使用以下方法成功地将它转换为非托管部分中的有效坐标:

    POINT pt = reinterpret_cast<MOUSEHOOKSTRUCT*>(lparam)->pt;
    int x = pt.x; // correct, e.g. 250
    int y = pt.y; // correct, e.g. 400

    但是,使用下面的翻译后,X和Y变成了乱码。

这是我的 C++ HOOKPROC 函数:

static LRESULT CALLBACK InternalMouseHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
// filter messages
// ...

// send lparam to C# code
}

这是我在 C# 中翻译 lparam 的方式:

IntPtr lparam = ...; // passed from unmanaged code and confirmed to be the same value
MouseHookStruct mouseData =
(MouseHookStruct)Marshal.PtrToStructure(lparam, typeof(MouseHookStruct));

下面是我如何将 POINTMOUSEHOOKSTRUCT 结构映射到 C#:

[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}

[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public IntPtr hwnd;
public uint wHitTestCode;
public IntPtr dwExtraInfo;
}

我做错了什么?

更新

C++ 中的

sizeof(MOUSEHOOKSTRUCT) 和 C# 中的 Marshal.SizeOf(typeof(MouseHookStruct)) 都打印 20

我使用的是 Windows 7 64 位,但 C# 和 C++ 代码均以 32 位编译和运行。

最佳答案

public class POINT

POINT 是原生 winapi 中的一个结构体。您倾向于在 C# 中将其声明为类。但不是什么时候:

public class MouseHookStruct
{
public POINT pt;
// etc...
}

pt 字段现在是一个引用,而不是一个值。编码器将尝试取消对 MOUSEHOOKSTRUCT.pt 的引用,就好像它是一个指针一样。非常值得注意的是,这不会更频繁地产生响亮的爆炸声,顺便说一句,预计会出现 AccessViolationException。可能您不走运,只在辅助显示器上进行过测试。

您必须将其声明为 struct

关于c# - 如何在托管代码中正确翻译 WH_MOUSE lparam,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33546319/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com