Win32RawInput.cs
author StephaneLenclud
Sun, 15 Feb 2015 21:48:07 +0100
changeset 63 4b8b058de215
parent 48 1eb878505ae1
child 76 831ebeeecfdf
permissions -rw-r--r--
HidDevice: Adding friendly name property.
sl@9
     1
using System;
sl@9
     2
using System.Runtime.InteropServices;
sl@9
     3
sl@9
     4
namespace Win32
sl@9
     5
{
sl@9
     6
sl@9
     7
    static partial class Function
sl@9
     8
    {
sl@9
     9
        [DllImport("User32.dll", SetLastError = true)]
sl@9
    10
		public extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
sl@9
    11
sl@9
    12
        [DllImport("User32.dll", SetLastError = true)]
sl@9
    13
		public extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
sl@9
    14
sl@9
    15
   		[DllImport("User32.dll", SetLastError=true)]
StephaneLenclud@60
    16
        public extern static int GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoType uiCommand, IntPtr pData, ref uint pcbSize);
StephaneLenclud@60
    17
StephaneLenclud@60
    18
        [DllImport("user32.dll", SetLastError = true)]
StephaneLenclud@60
    19
        public static extern int GetRawInputDeviceList(
StephaneLenclud@60
    20
            [In, Out] RAWINPUTDEVICELIST[] InputdeviceList,
StephaneLenclud@60
    21
            [In, Out] ref uint puiNumDevices,
StephaneLenclud@60
    22
            [In] uint cbSize);
StephaneLenclud@60
    23
sl@9
    24
    }
sl@9
    25
sl@15
    26
sl@15
    27
    static partial class Macro
sl@15
    28
    {
sl@15
    29
        /// <summary>
sl@15
    30
        /// Retrieves the input code from wParam in WM_INPUT.
sl@15
    31
        /// See RIM_INPUT and RIM_INPUTSINK.
sl@15
    32
        /// </summary>
sl@15
    33
        /// <param name="wParam"></param>
sl@15
    34
        /// <returns></returns>
sl@15
    35
        public static int GET_RAWINPUT_CODE_WPARAM(IntPtr wParam)
sl@15
    36
        {
sl@15
    37
            return (wParam.ToInt32() & 0xff);
sl@15
    38
        }
sl@15
    39
sl@15
    40
        public static int GET_DEVICE_LPARAM(IntPtr lParam)
sl@15
    41
        {
sl@15
    42
            return ((ushort)(HIWORD(lParam.ToInt32()) & Const.FAPPCOMMAND_MASK));
sl@15
    43
        }
sl@15
    44
sl@15
    45
        public static int HIWORD(int val)
sl@15
    46
        {
sl@15
    47
            return ((val >> 16) & 0xffff);
sl@15
    48
        }
sl@15
    49
sl@15
    50
sl@15
    51
        //#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
sl@15
    52
        //#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))        
sl@15
    53
        //#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
sl@15
    54
        //#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
sl@15
    55
sl@15
    56
        //#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
sl@15
    57
        //#define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
sl@15
    58
        //#define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
sl@15
    59
        //#define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
sl@15
    60
        //#define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
sl@15
    61
sl@15
    62
    }
sl@15
    63
sl@15
    64
sl@15
    65
sl@9
    66
    static partial class Const
sl@9
    67
    {
sl@9
    68
        /// <summary>
sl@15
    69
        /// Windows Messages
sl@15
    70
        /// </summary>
sl@15
    71
        public const int WM_KEYDOWN = 0x0100;
sl@15
    72
        public const int WM_INPUT = 0x00FF;
sl@15
    73
sl@9
    74
StephaneLenclud@60
    75
        //
sl@10
    76
        public const int RID_INPUT = 0x10000003;
sl@10
    77
        public const int RID_HEADER = 0x10000005;
sl@10
    78
sl@15
    79
        /// <summary>
sl@15
    80
        /// Possible value taken by wParam for WM_INPUT.
sl@15
    81
        /// <para />
sl@15
    82
        /// Input occurred while the application was in the foreground. The application must call DefWindowProc so the system can perform cleanup.
sl@15
    83
        /// </summary>
sl@15
    84
        public const int RIM_INPUT = 0;
sl@15
    85
        /// <summary>
sl@15
    86
        /// Possible value taken by wParam for WM_INPUT.
sl@15
    87
        /// <para />
sl@15
    88
        /// Input occurred while the application was not in the foreground. The application must call DefWindowProc so the system can perform the cleanup.
sl@15
    89
        /// </summary>
sl@15
    90
        public const int RIM_INPUTSINK = 1;
sl@15
    91
sl@15
    92
        /// <summary>
sl@15
    93
        /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a keyboard device.
sl@15
    94
        /// </summary>        
sl@15
    95
        public const uint RIDEV_APPKEYS = 0x00000400;
sl@15
    96
sl@15
    97
        /// <summary>
sl@15
    98
        /// If set, the mouse button click does not activate the other window.
sl@15
    99
        /// </summary>
sl@15
   100
	    public const uint RIDEV_CAPTUREMOUSE = 0x00000200;
sl@15
   101
        
sl@15
   102
        /// <summary>
sl@15
   103
        /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal.
sl@15
   104
        /// Windows XP:  This flag is not supported until Windows Vista
sl@15
   105
        /// </summary>
sl@15
   106
	    public const uint RIDEV_DEVNOTIFY = 0x00002000;
sl@15
   107
sl@15
   108
        /// <summary>
sl@15
   109
        /// If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with RIDEV_PAGEONLY.
sl@15
   110
        /// </summary>
sl@15
   111
        public const uint RIDEV_EXCLUDE = 0x00000010;
sl@15
   112
sl@15
   113
        /// <summary>
sl@15
   114
        /// If set, this enables the caller to receive input in the background only if the foreground application does not process it. In other words, if the foreground application is not registered for raw input, then the background application that is registered will receive the input.
sl@15
   115
        /// Windows XP:  This flag is not supported until Windows Vista
sl@15
   116
        /// </summary>
sl@15
   117
	    public const uint RIDEV_EXINPUTSINK = 0x00001000;
sl@15
   118
sl@15
   119
        /// <summary>
sl@15
   120
        /// If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must be specified.
sl@15
   121
        /// </summary>
sl@15
   122
	    public const uint RIDEV_INPUTSINK = 0x00000100;
sl@15
   123
sl@15
   124
	    /// <summary>
sl@15
   125
	    /// If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. RIDEV_NOHOTKEYS can be specified even if RIDEV_NOLEGACY is not specified and hwndTarget is NULL.
sl@15
   126
	    /// </summary>
sl@15
   127
        public const uint RIDEV_NOHOTKEYS = 0x00000200;
sl@15
   128
sl@15
   129
        /// <summary>
sl@15
   130
        /// If set, this prevents any devices specified by usUsagePage or usUsage from generating legacy messages. This is only for the mouse and keyboard. See Remarks.
sl@15
   131
        /// </summary>
sl@15
   132
        public const uint RIDEV_NOLEGACY = 0x00000030;
sl@15
   133
        
sl@15
   134
        /// <summary>
sl@15
   135
        /// If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that usUsage must be zero. To exclude a particular top level collection, use RIDEV_EXCLUDE.
sl@15
   136
        /// </summary>
sl@15
   137
        public const uint RIDEV_PAGEONLY = 0x00000020;
sl@15
   138
sl@15
   139
	    /// <summary>
sl@15
   140
        /// If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.
sl@15
   141
	    /// </summary>
sl@15
   142
        public const uint RIDEV_REMOVE = 0x00000001;
sl@15
   143
sl@15
   144
        public const int APPCOMMAND_BROWSER_BACKWARD = 1;
sl@15
   145
        public const int APPCOMMAND_VOLUME_MUTE = 8;
sl@15
   146
        public const int APPCOMMAND_VOLUME_DOWN = 9;
sl@15
   147
        public const int APPCOMMAND_VOLUME_UP = 10;
sl@15
   148
        public const int APPCOMMAND_MEDIA_NEXTTRACK = 11;
sl@15
   149
        public const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
sl@15
   150
        public const int APPCOMMAND_MEDIA_STOP = 13;
sl@15
   151
        public const int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;
sl@15
   152
        public const int APPCOMMAND_MEDIA_PLAY = 46;
sl@15
   153
        public const int APPCOMMAND_MEDIA_PAUSE = 47;
sl@15
   154
        public const int APPCOMMAND_MEDIA_RECORD = 48;
sl@15
   155
        public const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
sl@15
   156
        public const int APPCOMMAND_MEDIA_REWIND = 50;
sl@15
   157
        public const int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
sl@15
   158
        public const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
sl@15
   159
sl@15
   160
        public const int FAPPCOMMAND_MASK = 0xF000;
sl@15
   161
        public const int FAPPCOMMAND_MOUSE = 0x8000;
sl@15
   162
        public const int FAPPCOMMAND_KEY = 0;
StephaneLenclud@48
   163
		public const int FAPPCOMMAND_OEM = 0x1000;
sl@9
   164
    }
sl@9
   165
StephaneLenclud@60
   166
    /// <summary>
StephaneLenclud@60
   167
    /// Introduced this enum for consistency and easy of use.
StephaneLenclud@60
   168
    /// Naming of the Win32 constants were preserved.
StephaneLenclud@60
   169
    /// </summary>
StephaneLenclud@60
   170
    public enum RawInputDeviceType : uint
StephaneLenclud@60
   171
    {
StephaneLenclud@60
   172
        /// <summary>
StephaneLenclud@60
   173
        /// Data comes from a mouse.
StephaneLenclud@60
   174
        /// </summary>
StephaneLenclud@60
   175
        RIM_TYPEMOUSE = 0,
StephaneLenclud@60
   176
        /// <summary>
StephaneLenclud@60
   177
        /// Data comes from a keyboard.
StephaneLenclud@60
   178
        /// </summary>
StephaneLenclud@60
   179
        RIM_TYPEKEYBOARD = 1,
StephaneLenclud@60
   180
        /// <summary>
StephaneLenclud@60
   181
        /// Data comes from an HID that is not a keyboard or a mouse.
StephaneLenclud@60
   182
        /// </summary>
StephaneLenclud@60
   183
        RIM_TYPEHID = 2
StephaneLenclud@60
   184
    }
StephaneLenclud@60
   185
StephaneLenclud@60
   186
    /// <summary>
StephaneLenclud@60
   187
    /// Introduced this enum for consistency and easy of use.
StephaneLenclud@60
   188
    /// Naming of the Win32 constants were preserved.
StephaneLenclud@60
   189
    /// </summary>
StephaneLenclud@60
   190
    public enum RawInputDeviceInfoType : uint
StephaneLenclud@60
   191
    {
StephaneLenclud@60
   192
         /// <summary>
StephaneLenclud@60
   193
        /// GetRawInputDeviceInfo pData points to a string that contains the device name.
StephaneLenclud@60
   194
        /// </summary>
StephaneLenclud@60
   195
        RIDI_DEVICENAME = 0x20000007,
StephaneLenclud@60
   196
        /// <summary>
StephaneLenclud@60
   197
        /// GetRawInputDeviceInfo For this uiCommand only, the value in pcbSize is the character count (not the byte count).
StephaneLenclud@60
   198
        /// </summary>
StephaneLenclud@60
   199
        RIDI_DEVICEINFO = 0x2000000b,
StephaneLenclud@60
   200
        /// <summary>
StephaneLenclud@60
   201
        /// GetRawInputDeviceInfo pData points to an RID_DEVICE_INFO structure.
StephaneLenclud@60
   202
        /// </summary>
StephaneLenclud@60
   203
        RIDI_PREPARSEDDATA = 0x20000005
StephaneLenclud@60
   204
    }
StephaneLenclud@60
   205
sl@9
   206
sl@9
   207
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
StephaneLenclud@48
   208
    public struct RAWINPUTDEVICELIST
StephaneLenclud@48
   209
    {
StephaneLenclud@48
   210
        public IntPtr hDevice;
StephaneLenclud@60
   211
        public RawInputDeviceType dwType;
StephaneLenclud@48
   212
    }
StephaneLenclud@48
   213
StephaneLenclud@48
   214
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   215
    public struct RAWINPUTDEVICE
sl@9
   216
    {
sl@9
   217
        [MarshalAs(UnmanagedType.U2)]
sl@9
   218
        public ushort usUsagePage;
sl@9
   219
        [MarshalAs(UnmanagedType.U2)]
sl@9
   220
        public ushort usUsage;
sl@9
   221
        [MarshalAs(UnmanagedType.U4)]
sl@15
   222
        public uint dwFlags;
sl@9
   223
        public IntPtr hwndTarget;
sl@9
   224
    }
sl@9
   225
sl@9
   226
sl@9
   227
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   228
    public struct RAWINPUTHEADER
sl@9
   229
    {
sl@9
   230
        [MarshalAs(UnmanagedType.U4)]
StephaneLenclud@60
   231
        public RawInputDeviceType dwType;
sl@9
   232
        [MarshalAs(UnmanagedType.U4)]
sl@9
   233
        public int dwSize;
sl@9
   234
        public IntPtr hDevice;
sl@9
   235
        [MarshalAs(UnmanagedType.U4)]
sl@9
   236
        public int wParam;
sl@9
   237
    }
sl@9
   238
sl@9
   239
sl@9
   240
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   241
    public struct RAWHID
sl@9
   242
    {
sl@9
   243
        [MarshalAs(UnmanagedType.U4)]
sl@17
   244
        public uint dwSizeHid;
sl@9
   245
        [MarshalAs(UnmanagedType.U4)]
sl@17
   246
        public uint dwCount;
sl@9
   247
        //
sl@9
   248
        //BYTE  bRawData[1];
sl@9
   249
    }
sl@9
   250
sl@9
   251
sl@9
   252
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   253
    public struct BUTTONSSTR
sl@9
   254
    {
sl@9
   255
        [MarshalAs(UnmanagedType.U2)]
sl@9
   256
        public ushort usButtonFlags;
sl@9
   257
        [MarshalAs(UnmanagedType.U2)]
sl@9
   258
        public ushort usButtonData;
sl@9
   259
    }
sl@9
   260
sl@9
   261
sl@9
   262
    [StructLayout(LayoutKind.Explicit, Pack = 1)]
sl@40
   263
    public struct RAWMOUSE
sl@9
   264
    {
sl@9
   265
        [MarshalAs(UnmanagedType.U2)]
sl@9
   266
        [FieldOffset(0)]
sl@9
   267
        public ushort usFlags;
sl@9
   268
        [MarshalAs(UnmanagedType.U4)]
sl@9
   269
        [FieldOffset(4)]
sl@9
   270
        public uint ulButtons;
sl@9
   271
        [FieldOffset(4)]
sl@9
   272
        public BUTTONSSTR buttonsStr;
sl@9
   273
        [MarshalAs(UnmanagedType.U4)]
sl@9
   274
        [FieldOffset(8)]
sl@9
   275
        public uint ulRawButtons;
sl@9
   276
        [MarshalAs(UnmanagedType.U4)]
sl@9
   277
        [FieldOffset(12)]
sl@9
   278
        public int lLastX;
sl@9
   279
        [MarshalAs(UnmanagedType.U4)]
sl@9
   280
        [FieldOffset(16)]
sl@9
   281
        public int lLastY;
sl@9
   282
        [MarshalAs(UnmanagedType.U4)]
sl@9
   283
        [FieldOffset(20)]
sl@9
   284
        public uint ulExtraInformation;
sl@9
   285
    }
sl@9
   286
sl@9
   287
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   288
    public struct RAWKEYBOARD
sl@9
   289
    {
sl@9
   290
        [MarshalAs(UnmanagedType.U2)]
sl@9
   291
        public ushort MakeCode;
sl@9
   292
        [MarshalAs(UnmanagedType.U2)]
sl@9
   293
        public ushort Flags;
sl@9
   294
        [MarshalAs(UnmanagedType.U2)]
sl@9
   295
        public ushort Reserved;
sl@9
   296
        [MarshalAs(UnmanagedType.U2)]
sl@9
   297
        public ushort VKey;
sl@9
   298
        [MarshalAs(UnmanagedType.U4)]
sl@9
   299
        public uint Message;
sl@9
   300
        [MarshalAs(UnmanagedType.U4)]
sl@9
   301
        public uint ExtraInformation;
sl@9
   302
    }
sl@9
   303
sl@9
   304
sl@9
   305
    [StructLayout(LayoutKind.Explicit, Pack = 1)]
sl@40
   306
    public struct RAWINPUT
sl@9
   307
    {
sl@9
   308
        [FieldOffset(0)]
sl@9
   309
        public RAWINPUTHEADER header;
sl@9
   310
        [FieldOffset(16)]
sl@9
   311
        public RAWMOUSE mouse;
sl@9
   312
        [FieldOffset(16)]
sl@9
   313
        public RAWKEYBOARD keyboard;
sl@9
   314
        [FieldOffset(16)]
sl@9
   315
        public RAWHID hid;
sl@9
   316
    }
sl@9
   317
sl@9
   318
sl@9
   319
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   320
    public struct RID_DEVICE_INFO_MOUSE
sl@9
   321
    {
sl@9
   322
        public uint dwId;
sl@9
   323
        public uint dwNumberOfButtons;
sl@9
   324
        public uint dwSampleRate;
sl@9
   325
        public bool fHasHorizontalWheel;
sl@9
   326
    }
sl@9
   327
sl@9
   328
sl@9
   329
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   330
    public struct RID_DEVICE_INFO_KEYBOARD
sl@9
   331
    {
sl@9
   332
        public uint dwType;
sl@9
   333
        public uint dwSubType;
sl@9
   334
        public uint dwKeyboardMode;
sl@9
   335
        public uint dwNumberOfFunctionKeys;
sl@9
   336
        public uint dwNumberOfIndicators;
sl@9
   337
        public uint dwNumberOfKeysTotal;
sl@9
   338
    }
sl@9
   339
sl@9
   340
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
sl@40
   341
    public struct RID_DEVICE_INFO_HID
sl@9
   342
    {
sl@9
   343
        public uint dwVendorId;
sl@9
   344
        public uint dwProductId;
sl@9
   345
        public uint dwVersionNumber;
sl@9
   346
        public ushort usUsagePage;
sl@9
   347
        public ushort usUsage;
sl@9
   348
    }
sl@9
   349
sl@9
   350
    [StructLayout(LayoutKind.Explicit, Pack = 1)]
sl@40
   351
    public struct RID_DEVICE_INFO
sl@9
   352
    {
sl@9
   353
        [FieldOffset(0)]
sl@9
   354
        public uint cbSize;
sl@9
   355
        [FieldOffset(4)]
StephaneLenclud@60
   356
        [MarshalAsAttribute(UnmanagedType.U4)]
StephaneLenclud@60
   357
        public RawInputDeviceType dwType;
sl@9
   358
        [FieldOffset(8)]
sl@9
   359
        public RID_DEVICE_INFO_MOUSE mouse;
sl@9
   360
        [FieldOffset(8)]
sl@9
   361
        public RID_DEVICE_INFO_KEYBOARD keyboard;
sl@9
   362
        [FieldOffset(8)]
sl@9
   363
        public RID_DEVICE_INFO_HID hid;
sl@9
   364
    }
sl@9
   365
sl@9
   366
sl@9
   367
}