2016-03-04 25 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