我正在尝试将系统的原始鼠标输入到C#应用程序中。我正在使用WM_INPUT
(MSDN link)来访问数据。为此,我使用的是user32.dll。这个(stackoverflow link)帮助我编写了API Wrapper。
以下代码段显示了WndProc
方法。 rimTypeMouseCount
已经显示Windows消息似乎正确获取。当我向上或向下转动鼠标的轮询速率时,我也可以通过检查计数来看到这一点 - 较低的轮询速率意味着较低的计数,较高的轮询速率意味着在记录相等的时间间隔时较高的计数。到目前为止,这很好。
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x00ff) {
uint dwSize = 40;
byte[] raw = new byte[40];
IntPtr rawPtr = Marshal.AllocHGlobal(raw.Length);
APIWrapper.GetRawInputData((IntPtr)m.LParam, 0x10000003, rawPtr, ref dwSize, Marshal.SizeOf(new APIWrapper.RAWINPUTHEADER()));
Marshal.Copy(rawPtr, raw, 0, 40);
GCHandle handle = GCHandle.Alloc(raw, GCHandleType.Pinned);
APIWrapper.RAWINPUT rawData = (APIWrapper.RAWINPUT)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(APIWrapper.RAWINPUT));
handle.Free();
if (rawData.header.dwType == 0)
{
rimTypeMouseCount++;
logMouseX = logMouseX + rawData.mouse.lLastX.ToString() + Environment.NewLine;
logMouseY = logMouseY + rawData.mouse.lLastY.ToString() + Environment.NewLine;
}
}
base.WndProc(ref m);
}
[StructLayout(LayoutKind.Explicit)]
internal struct RAWINPUT
{
[FieldOffset(0)]
public RAWINPUTHEADER header;
[FieldOffset(16 + 8)]
public RAWMOUSE mouse;
[FieldOffset(16 + 8)]
public RAWKEYBOARD keyboard;
[FieldOffset(16 + 8)]
public RAWHID hid;
}
但logMouseX
和logMouseY
存在问题。那些字符串只需在每次调用时附加x和y轴的鼠标增量。不幸的是,logMouseX
仅记录值0或65535,而logMouseY
仅记录0。我还尝试记录鼠标左键等向上/向下等消息。实际上似乎没有任何作用。对我而言,似乎有点数字可能是随机的或类似的东西。
这就是我(我想)做的事情:
APIWrapper.GetRawInputData(...)
需要一个指向字节数组的指针。所以我只是通过编组在非托管内存中分配空间并得到一个指针作为结果。RAWINPUT
的字段,我需要将字节数组转换为RAWINPUT
结构。可能是因为我搞乱了吗?也许像Big-Endian和Little-Endian这样的东西混在一起?
我发现使用rawData.mouse.lLastX
&时得到的值rawData.mouse.lLastY
表现得像这样:
我发现使用rawDataL.hid.pbRawData
包含有关此移动的更多信息。在那里,我得到的值取决于我移动鼠标的速度。不幸的是,没有X或Y组件,所以这只适用于一个轴(向下/向上)。
uint dwSize = 40;
byte[] raw = new byte[40];
GCHandle handle = GCHandle.Alloc(raw, GCHandleType.Pinned);
APIWrapper.GetRawInputData((IntPtr)m.LParam, 0x10000003, handle.AddrOfPinnedObject(), ref dwSize, Marshal.SizeOf(new APIWrapper.RAWINPUTHEADER()));
APIWrapper.RAWINPUT rawData = (APIWrapper.RAWINPUT)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(APIWrapper.RAWINPUT));
if (rawData.header.dwType == 0)
{
// accessing data
}
handle.Free();
答案 0 :(得分:0)
我在这里发布了我的问题(MSDN link),我被告知RAWMOUSE结构的偏移量不正确。
所以我只记录原始数据数组的所有字节,最后可以看到我需要的所有数据,因此可以看到正确的偏移量。我想使用32位或64位机器时,偏移量会有所不同。以下是相关的代码更改:
WndProc改变:
RawMouseData rawData = (RawMouseData) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(RawMouseData));
RawMouseData struct:
[StructLayout(LayoutKind.Explicit)]
internal struct RawMouseData
{
[FieldOffset(20)]
public ButtonFlags buttonFlags;
[FieldOffset(22)]
public ushort buttonData;
[FieldOffset(28)]
public int lastX;
[FieldOffset(32)]
public int lastY;
}
这是每个鼠标移动方向的原始字节数组的数据日志的样子:
Downwards: Upwards:
Byte 29: 0 Byte 29: 0
Byte 30: 0 Byte 30: 0
Byte 31: 0 Byte 31: 0
Byte 32: 0 Byte 32: 0
Byte 33: 1 Byte 33: 255
Byte 34: 0 Byte 34: 255
Byte 35: 0 Byte 35: 255
Byte 36: 0 Byte 36: 255
Left: Right:
Byte 29: 255 Byte 29: 1
Byte 30: 255 Byte 30: 0
Byte 31: 255 Byte 31: 0
Byte 32: 255 Byte 32: 0
Byte 33: 0 Byte 33: 0
Byte 34: 0 Byte 34: 0
Byte 35: 0 Byte 35: 0
Byte 36: 0 Byte 36: 0
我移动鼠标的速度越快(向下或向右移动)或越小(向上或向左移动时)值越大。