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