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