2012-09-13 121 views
0

我有一個32位Windows應用程序(與平臺目標:x86)。它處理Windows消息以識別按下的鍵盤按鍵。 我需要將其平臺目標更改爲:對於64位平臺的任何CPU,但在將其平臺類型更改爲任何CPU時,它不起作用。當我調試時,我發現兩個配置的rawinput.keyboard.Message的值有差異,例如,當控制鍵被按下時,對於x86而言,它是256,但是對於任何CPU是29。是由窗口消息的Lparam值填充的uint類型的變量。鍵盤消息在32位和64位

我怎樣才能使它通用?

CODE:

private void ProcessInputCommand(Message message) 
    { 
     uint dwSize = 0; 

     // First call to GetRawInputData sets the value of dwSize, 
     // which can then be used to allocate the appropriate amount of memory, 
     // storing the pointer in "buffer". 
     UnsafeNativeMethods.GetRawInputData(message.LParam, 
         UnsafeNativeMethods.RID_INPUT, IntPtr.Zero, 
         ref dwSize, 
         (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))); 

     IntPtr buffer = Marshal.AllocHGlobal((int)dwSize); 
     try 
     { 
      // Check that buffer points to something, and if so, 
      // call GetRawInputData again to fill the allocated memory 
      // with information about the input 
      if (buffer != IntPtr.Zero && 
       UnsafeNativeMethods.GetRawInputData(message.LParam, 
           UnsafeNativeMethods.RID_INPUT, 
           buffer, 
           ref dwSize, 
           (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) == dwSize) 
      { 
       // Store the message information in "raw", then check 
       // that the input comes from a keyboard device before 
       // processing it to raise an appropriate KeyPressed event. 

       RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT)); 

       if (raw.header.dwType == UnsafeNativeMethods.RIM_TYPEKEYBOARD) 
       { 
        // Filter for Key Down events and then retrieve information 
        // about the keystroke 
        if (raw.keyboard.Message == UnsafeNativeMethods.WM_KEYDOWN || raw.keyboard.Message == UnsafeNativeMethods.WM_SYSKEYDOWN) 
        { 
         ushort key = raw.keyboard.VKey; 
        } 

(代碼的其餘部分來處理鍵) 。 。

GetRawInputData:

[DllImport("User32.dll")] 
    extern internal static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader); 
+1

請從後'Lparam' – Rotem

+0

嗯提取'uint'的相關代碼。如何定義'GetRawInputData'? (也許所需的P/Invoke屬性不存在?) – Vlad

+1

您正在使用x86/x64安全版本的'RAWINPUT'結構嗎?見http://www.pinvoke.net/default.aspx/Structures/RAWINPUT.html – Rotem

回答

7

RAWINPUT結構使用顯式的佈局,這需要不同的字段偏移爲64位。

Pinvoke.Net提供的x86/x64操作系統的安全實施的RAWINPUT,您可以使用:

/// <summary> 
/// Contains the raw input from a device. 
/// </summary> 
[StructLayout(LayoutKind.Sequential)] 
public struct RawInput 
{ 
    /// <summary> 
    /// Header for the data. 
    /// </summary> 
    public RawInputHeader Header; 
    public Union Data; 
    [StructLayout(LayoutKind.Explicit)] 
    public struct Union 
    { 
     /// <summary> 
     /// Mouse raw input data. 
     /// </summary> 
     [FieldOffset(0)] 
     public RawMouse Mouse; 
     /// <summary> 
     /// Keyboard raw input data. 
     /// </summary> 
     [FieldOffset(0)] 
     public RawKeyboard Keyboard; 
     /// <summary> 
     /// HID raw input data. 
     /// </summary> 
     [FieldOffset(0)] 
     public RawHID HID; 
    } 
}