2016-03-04 198 views
1

MSDN:https://msdn.microsoft.com/de-de/library/windows/desktop/ms645562(v=vs.85).aspxRAWINPUT结构在C#

我目前的C#结构是这样的:

[StructLayout(LayoutKind.Explicit)] 
public struct RawInput 
{ 
    [System.Runtime.InteropServices.FieldOffset(0)] 
    public RawInputHeader Header; 

    [System.Runtime.InteropServices.FieldOffset(16)] 
    public RawInputData Data; 
} 

[StructLayout(LayoutKind.Explicit)] 
public struct RawInputData 
{ 
    [FieldOffset(0)] 
    public RawMouse Mouse; 
    [FieldOffset(0)] 
    public RawKeyboard Keyboard; 
    [FieldOffset(0)] 
    public RawHID HID; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct RawHID 
{ 
    public int Size; 
    public int Count; 
    public IntPtr Data; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct RawInputHeader 
{ 
    public RawInputDeviceType Type; 
    public int Size;  
    public IntPtr Device; 
    public IntPtr Param;  
    public static int RawInputHeaderSize = Marshal.SizeOf<RawInputHeader>(); 
} 

public struct RawMouse 
{ 
    public RawMouseState Flags; 
    private short Buttons; 
    public RawInputMouseState ButtonFlags; 
    public short ButtonData; 
    public int RawButtons; 
    public int LastX; 
    public int LastY; 
    public int ExtraInformation;    
    public static readonly int Size = Marshal.SizeOf(typeof(RawMouse)); 
} 

public struct RawKeyboard 
{ 
    public short MakeCode; 
    public RawInputKeyboardFlags Flags; 
    private readonly short Reserved; 
    public VirtualKeys VirtualKey; 
    public WindowMessage Message; 
    public int ExtraInformation;    
    public static readonly int Size = Marshal.SizeOf(typeof(RawKeyboard)); 
} 

[DllImport("User32", SetLastError = true)] 
public static extern int GetRawInputData(
     IntPtr rawInput, RawInputDataType command, 
     [Out] out RawInput data, [In, Out] ref int size, int sizeHeader); 

[DllImport("User32", SetLastError = true)] 
public static extern int GetRawInputData(
     IntPtr rawInput, RawInputDataType command, 
     IntPtr data, [In, Out] ref int size, int sizeHeader); 

我的第一个问题是,是布局确定为32位和64位?

现在,我尝试让原始HID数据:

int size = 0; 
Win32API.GetRawInputData(
    message.LParam, 
    Win32API.RawInputDataType.Header, 
    IntPtr.Zero, ref size, 
    Win32API.RawInputHeader.RawInputHeaderSize); 


Win32API.RawInput ri; 
Win32API.GetRawInputData(
    message.LParam, 
     Win32API.RawInputDataType.Input, 
     out ri, 
     ref size, 
     Win32API.RawInputHeader.RawInputHeaderSize); 

现在,我尝试让字节数组:

byte[] bytes = new byte[ri.Data.HID.Count]; 
Marshal.Copy(ri.Data.HID.Data, bytes, 0, ri.Data.HID.Count); 

调试器只有几步之遥了这两条线。我认为布局是错误的,但林不知道。 HID结构的数量和大小始终为零。

有谁知道错误在哪里?

谢谢!

+0

从不,*从不*,**从不**忽略winapi函数的返回值。如果你不检查错误,那么你不会找到一个错误。失败时抛出一个Win32Exception。 –

回答

1

看起来你已经从pinvoke.net获得这些声明,但不幸的是这不是一个可靠的来源。有很多错误。

RawInput结构声明不正确。你应该使用顺序布局。只对联合使用显式布局。

[StructLayout(LayoutKind.Sequential)] 
public struct RawInput 
{ 
    public RawInputHeader Header; 
    public RawInputData Data; 
} 

遵循与工会的规则是:

  • 声明为每一联盟类型。为每个成员使用字段偏移量为0的显式布局。确保你定义了所有的成员,而不仅仅是你认为你需要的成员。如果您省略成员,则联合类型可能大小错误。
  • 对结构使用顺序布局,并将联合类型包括为这些结构的成员。

我们看不到RawInputHeader的声明,所以我们不知道这是否正确。我们也不能看到RawMouseRawKeyboard。所以他们可能是错的。

RawHID的声明是错误的。这是一个可变长度结构,最终成员bRawData是一个内联字节数组。您错误地声明为IntPtr。 C#编组人员无法为你编组。

因为RawHID是可变长度的,所以包含结构也是可变长度的。这意味着您需要为RawInput结构分配非托管内存,并将其作为IntPtr传递给GetRawInputData。您可以使用Marshal.PtrToStructure来读出大部分字段,但要读出bRawData需要多一点工作。

您的代码无法执行错误检查。您必须按照记录检查错误。

+0

我已将其他结构添加到初始帖子。 – Kevin

+0

你必须解决所有的问题 –

+0

我已经得到了它的工作。我想我得到一个指向bRawData中的字节数组的指针。我用Marshal.PtrToStructure与rawinput结构的指针+头结构的大小一起管理它。 – Kevin