0

私は32ビットのWindowsアプリケーションを持っています(プラットフォームターゲット:x86)。Windows メッセージを処理して、押されたキーボード キーを識別します。プラットフォーム ターゲットを次のように変更する必要があります: 64 ビット プラットフォームの任意の CPU ですが、プラットフォーム タイプを任意の CPU に変更すると、機能しません。デバッグしたところ、両方の構成で rawinput.keyboard.Message の値に違いがあることがわかりました。たとえば、コントロール キーを押すと、x86 では 256 ですが、Any CPU では 29 です。

ここで、Message は、ウィンドウ メッセージの Lparam 値から埋められる uint 型の変数です。

どうすればジェネリックにできますか?

コード:

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);
4

1 に答える 1

7

構造体は明示的なレイアウトを使用します。RAWINPUTこれには、64ビット用に異なるフィールドオフセットが必要です。

Pinvoke.NetRAWINPUTは、以下を使用できるx86/x64の安全な実装を提供します。

/// <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;
    }
}
于 2012-09-13T10:21:43.210 に答える