Now capable of handling WM_INPUT when in background.
authorsl
Mon, 24 Nov 2014 18:20:45 +0100
changeset 152044181ade12
parent 14 0d9f479cbbf7
child 16 9a3e77655031
Now capable of handling WM_INPUT when in background.
Form1.cs
RemoteControlDevice.cs
Win32RawInput.cs
     1.1 --- a/Form1.cs	Mon Nov 24 16:46:26 2014 +0100
     1.2 +++ b/Form1.cs	Mon Nov 24 18:20:45 2014 +0100
     1.3 @@ -32,9 +32,7 @@
     1.4  			_timer = new Timer();
     1.5  			_timer.Interval = 3000;
     1.6  			_timer.Enabled = false;
     1.7 -			_timer.Tick +=new EventHandler(_timer_Tick);
     1.8 -			_remote = new RemoteControlDevice();
     1.9 -			_remote.ButtonPressed +=new Devices.RemoteControl.RemoteControlDevice.RemoteControlDeviceEventHandler(_remote_ButtonPressed);
    1.10 +			_timer.Tick +=new EventHandler(_timer_Tick);            
    1.11  		}
    1.12  
    1.13  		/// <summary>
    1.14 @@ -110,13 +108,17 @@
    1.15  
    1.16  		private void Form1_Load(object sender, System.EventArgs e)
    1.17  		{
    1.18 -
    1.19 +            _remote = new RemoteControlDevice(this.Handle);
    1.20 +            _remote.ButtonPressed += new Devices.RemoteControl.RemoteControlDevice.RemoteControlDeviceEventHandler(_remote_ButtonPressed);
    1.21  		}
    1.22  
    1.23  
    1.24  		protected override void WndProc(ref Message message)
    1.25  		{
    1.26 -			_remote.ProcessMessage(message);
    1.27 +            if (_remote != null)
    1.28 +            {
    1.29 +                _remote.ProcessMessage(message);
    1.30 +            }
    1.31  			base.WndProc(ref message);
    1.32  		}
    1.33  
     2.1 --- a/RemoteControlDevice.cs	Mon Nov 24 16:46:26 2014 +0100
     2.2 +++ b/RemoteControlDevice.cs	Mon Nov 24 18:20:45 2014 +0100
     2.3 @@ -126,45 +126,17 @@
     2.4  
     2.5  	public sealed class RemoteControlDevice
     2.6  	{
     2.7 -		private const int WM_KEYDOWN	= 0x0100;
     2.8 -		private const int WM_APPCOMMAND	= 0x0319;
     2.9 -		private const int WM_INPUT		= 0x00FF;
    2.10 -
    2.11 -		private const int APPCOMMAND_BROWSER_BACKWARD   = 1;
    2.12 -		private const int APPCOMMAND_VOLUME_MUTE        = 8;
    2.13 -		private const int APPCOMMAND_VOLUME_DOWN        = 9;
    2.14 -		private const int APPCOMMAND_VOLUME_UP          = 10;
    2.15 -		private const int APPCOMMAND_MEDIA_NEXTTRACK    = 11;
    2.16 -		private const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
    2.17 -		private const int APPCOMMAND_MEDIA_STOP         = 13;
    2.18 -		private const int APPCOMMAND_MEDIA_PLAY_PAUSE   = 14;
    2.19 -		private const int APPCOMMAND_MEDIA_PLAY         = 46;
    2.20 -		private const int APPCOMMAND_MEDIA_PAUSE        = 47;
    2.21 -		private const int APPCOMMAND_MEDIA_RECORD       = 48;
    2.22 -		private const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
    2.23 -		private const int APPCOMMAND_MEDIA_REWIND       = 50;
    2.24 -		private const int APPCOMMAND_MEDIA_CHANNEL_UP   = 51;
    2.25 -		private const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
    2.26 -
    2.27 -		private const int FAPPCOMMAND_MASK				= 0xF000;
    2.28 -		private const int FAPPCOMMAND_MOUSE				= 0x8000;
    2.29 -		private const int FAPPCOMMAND_KEY				= 0;
    2.30 -		private const int FAPPCOMMAND_OEM				= 0x1000;
    2.31 -
    2.32 -
    2.33 -
    2.34  		public delegate void RemoteControlDeviceEventHandler(object sender, RemoteControlEventArgs e);
    2.35  		public event RemoteControlDeviceEventHandler ButtonPressed;
    2.36  
    2.37          public delegate void HidUsageHandler(ushort aUsage);
    2.38          
    2.39  
    2.40 -
    2.41  		//-------------------------------------------------------------
    2.42  		// constructors
    2.43  		//-------------------------------------------------------------
    2.44  
    2.45 -		public RemoteControlDevice()
    2.46 +		public RemoteControlDevice(IntPtr aHWND)
    2.47  		{
    2.48  			// Register the input device to receive the commands from the
    2.49  			// remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp
    2.50 @@ -174,22 +146,22 @@
    2.51  
    2.52  			rid[0].usUsagePage = 0xFFBC;
    2.53  			rid[0].usUsage = 0x88;
    2.54 -			rid[0].dwFlags = 0;
    2.55 +            rid[0].dwFlags = Const.RIDEV_EXINPUTSINK;
    2.56 +            rid[0].hwndTarget = aHWND;
    2.57  
    2.58  			rid[1].usUsagePage = 0x0C;
    2.59  			rid[1].usUsage = 0x01;
    2.60 -			rid[1].dwFlags = 0;
    2.61 +            rid[1].dwFlags = Const.RIDEV_EXINPUTSINK;
    2.62 +            rid[1].hwndTarget = aHWND;
    2.63  
    2.64  			rid[2].usUsagePage = 0x0C;
    2.65  			rid[2].usUsage = 0x80;
    2.66 -			rid[2].dwFlags = 0;
    2.67 +            rid[2].dwFlags = Const.RIDEV_EXINPUTSINK;
    2.68 +            rid[2].hwndTarget = aHWND;
    2.69  
    2.70 -			if (!Function.RegisterRawInputDevices(rid,
    2.71 -				(uint) rid.Length,
    2.72 -				(uint) Marshal.SizeOf(rid[0]))
    2.73 -				)
    2.74 +			if (!Function.RegisterRawInputDevices(rid,(uint) rid.Length,(uint) Marshal.SizeOf(rid[0])))
    2.75  			{
    2.76 -				throw new ApplicationException("Failed to register raw input devices.");
    2.77 +                throw new ApplicationException("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
    2.78  			}
    2.79  		}
    2.80  
    2.81 @@ -200,19 +172,15 @@
    2.82  
    2.83  		public void ProcessMessage(Message message)
    2.84  		{
    2.85 -		int param;
    2.86 -
    2.87  			switch (message.Msg)
    2.88  			{
    2.89 -				case WM_KEYDOWN:
    2.90 -					param = message.WParam.ToInt32();
    2.91 -					ProcessKeyDown(param);
    2.92 +				case Const.WM_KEYDOWN:
    2.93 +                    ProcessKeyDown(message.WParam);
    2.94  					break;
    2.95 -				case WM_APPCOMMAND:
    2.96 -					param = message.LParam.ToInt32();
    2.97 -					ProcessAppCommand(param);
    2.98 +                case Const.WM_APPCOMMAND:
    2.99 +					ProcessAppCommand(message.LParam);
   2.100  					break;
   2.101 -				case WM_INPUT:
   2.102 +                case Const.WM_INPUT:
   2.103  					ProcessInputCommand(ref message);
   2.104                      message.Result = new IntPtr(0);
   2.105  					break;
   2.106 @@ -225,11 +193,11 @@
   2.107  		// methods (helpers)
   2.108  		//-------------------------------------------------------------
   2.109  
   2.110 -		private void ProcessKeyDown(int param)
   2.111 +		private void ProcessKeyDown(IntPtr wParam)
   2.112  		{
   2.113  			RemoteControlButton rcb = RemoteControlButton.Unknown;
   2.114  
   2.115 -			switch (param)
   2.116 +            switch (wParam.ToInt32())
   2.117  			{
   2.118  				case (int) Keys.Escape:
   2.119  					rcb = RemoteControlButton.Clear;
   2.120 @@ -282,67 +250,68 @@
   2.121  			}
   2.122  
   2.123  			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
   2.124 -				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
   2.125 +				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(wParam)));
   2.126  		}
   2.127  
   2.128  
   2.129 -		private void ProcessAppCommand(int param)
   2.130 +		private void ProcessAppCommand(IntPtr lParam)
   2.131  		{
   2.132  			RemoteControlButton rcb = RemoteControlButton.Unknown;
   2.133  
   2.134 -			int cmd	= (int) (((ushort) (param >> 16)) & ~FAPPCOMMAND_MASK);
   2.135 +            int cmd = Macro.GET_APPCOMMAND_LPARAM(lParam);
   2.136 +                //(int) (((ushort) (param >> 16)) & ~Const.FAPPCOMMAND_MASK);
   2.137  
   2.138  			switch (cmd)
   2.139  			{
   2.140 -				case APPCOMMAND_BROWSER_BACKWARD:
   2.141 +                case Const.APPCOMMAND_BROWSER_BACKWARD:
   2.142  					rcb = RemoteControlButton.Back;
   2.143  					break;
   2.144 -				case APPCOMMAND_MEDIA_CHANNEL_DOWN:
   2.145 +                case Const.APPCOMMAND_MEDIA_CHANNEL_DOWN:
   2.146  					rcb = RemoteControlButton.ChannelDown;
   2.147  					break;
   2.148 -				case APPCOMMAND_MEDIA_CHANNEL_UP:
   2.149 +                case Const.APPCOMMAND_MEDIA_CHANNEL_UP:
   2.150  					rcb = RemoteControlButton.ChannelUp;
   2.151  					break;
   2.152 -				case APPCOMMAND_MEDIA_FAST_FORWARD:
   2.153 +                case Const.APPCOMMAND_MEDIA_FAST_FORWARD:
   2.154  					rcb = RemoteControlButton.FastForward;
   2.155  					break;
   2.156 -				case APPCOMMAND_VOLUME_MUTE:
   2.157 +                case Const.APPCOMMAND_VOLUME_MUTE:
   2.158  					rcb = RemoteControlButton.VolumeMute;
   2.159  					break;
   2.160 -				case APPCOMMAND_MEDIA_PAUSE:
   2.161 +                case Const.APPCOMMAND_MEDIA_PAUSE:
   2.162  					rcb = RemoteControlButton.Pause;
   2.163  					break;
   2.164 -				case APPCOMMAND_MEDIA_PLAY:
   2.165 +                case Const.APPCOMMAND_MEDIA_PLAY:
   2.166  					rcb = RemoteControlButton.Play;
   2.167  					break;
   2.168 -                case APPCOMMAND_MEDIA_PLAY_PAUSE:
   2.169 +                case Const.APPCOMMAND_MEDIA_PLAY_PAUSE:
   2.170                      rcb = RemoteControlButton.PlayPause;
   2.171                      break;
   2.172 -				case APPCOMMAND_MEDIA_RECORD:
   2.173 +                case Const.APPCOMMAND_MEDIA_RECORD:
   2.174  					rcb = RemoteControlButton.Record;
   2.175  					break;
   2.176 -				case APPCOMMAND_MEDIA_PREVIOUSTRACK:
   2.177 +                case Const.APPCOMMAND_MEDIA_PREVIOUSTRACK:
   2.178  					rcb = RemoteControlButton.PreviousTrack;
   2.179  					break;
   2.180 -				case APPCOMMAND_MEDIA_REWIND:
   2.181 +                case Const.APPCOMMAND_MEDIA_REWIND:
   2.182  					rcb = RemoteControlButton.Rewind;
   2.183  					break;
   2.184 -				case APPCOMMAND_MEDIA_NEXTTRACK:
   2.185 +                case Const.APPCOMMAND_MEDIA_NEXTTRACK:
   2.186  					rcb = RemoteControlButton.NextTrack;
   2.187  					break;
   2.188 -				case APPCOMMAND_MEDIA_STOP:
   2.189 +                case Const.APPCOMMAND_MEDIA_STOP:
   2.190  					rcb = RemoteControlButton.Stop;
   2.191  					break;
   2.192 -				case APPCOMMAND_VOLUME_DOWN:
   2.193 +                case Const.APPCOMMAND_VOLUME_DOWN:
   2.194  					rcb = RemoteControlButton.VolumeDown;
   2.195  					break;
   2.196 -				case APPCOMMAND_VOLUME_UP:
   2.197 +                case Const.APPCOMMAND_VOLUME_UP:
   2.198  					rcb = RemoteControlButton.VolumeUp;
   2.199  					break;
   2.200  			}
   2.201  
   2.202  			if (this.ButtonPressed != null && rcb != RemoteControlButton.Unknown)
   2.203 -				this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(param)));
   2.204 +                this.ButtonPressed(this, new RemoteControlEventArgs(rcb, GetDevice(lParam)));
   2.205  		}
   2.206  
   2.207          /// <summary>
   2.208 @@ -413,8 +382,18 @@
   2.209  
   2.210  		private void ProcessInputCommand(ref Message message)
   2.211  		{
   2.212 +            //We received a WM_INPUT message
   2.213              Debug.WriteLine("================WM_INPUT================");
   2.214  
   2.215 +            //Check if we received this message while in background or foreground
   2.216 +            if (Macro.GET_RAWINPUT_CODE_WPARAM(message.WParam) == Const.RIM_INPUT)
   2.217 +            {
   2.218 +                Debug.WriteLine("================FOREGROUND");
   2.219 +            }
   2.220 +            else if (Macro.GET_RAWINPUT_CODE_WPARAM(message.WParam) == Const.RIM_INPUTSINK)
   2.221 +            {
   2.222 +                Debug.WriteLine("================BACKGROUND");
   2.223 +            }
   2.224  
   2.225              //Declare a pointer
   2.226              IntPtr rawInputBuffer = IntPtr.Zero;
   2.227 @@ -535,16 +514,16 @@
   2.228  		}
   2.229  
   2.230  
   2.231 -		private InputDevice GetDevice(int param)
   2.232 +		private InputDevice GetDevice(IntPtr lParam)
   2.233  		{
   2.234  			InputDevice inputDevice;
   2.235  
   2.236 -			switch ((int) (((ushort) (param >> 16)) & FAPPCOMMAND_MASK))
   2.237 +            switch (Macro.GET_DEVICE_LPARAM(lParam))
   2.238  			{
   2.239 -				case FAPPCOMMAND_OEM:
   2.240 +				case Const.FAPPCOMMAND_OEM:
   2.241  					inputDevice = InputDevice.OEM;
   2.242  					break;
   2.243 -				case FAPPCOMMAND_MOUSE:
   2.244 +				case Const.FAPPCOMMAND_MOUSE:
   2.245  					inputDevice = InputDevice.Mouse;
   2.246  					break;
   2.247  				default:
     3.1 --- a/Win32RawInput.cs	Mon Nov 24 16:46:26 2014 +0100
     3.2 +++ b/Win32RawInput.cs	Mon Nov 24 18:20:45 2014 +0100
     3.3 @@ -16,9 +16,61 @@
     3.4  		public extern static int GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);
     3.5      }
     3.6  
     3.7 +
     3.8 +    static partial class Macro
     3.9 +    {
    3.10 +        /// <summary>
    3.11 +        /// Retrieves the input code from wParam in WM_INPUT.
    3.12 +        /// See RIM_INPUT and RIM_INPUTSINK.
    3.13 +        /// </summary>
    3.14 +        /// <param name="wParam"></param>
    3.15 +        /// <returns></returns>
    3.16 +        public static int GET_RAWINPUT_CODE_WPARAM(IntPtr wParam)
    3.17 +        {
    3.18 +            return (wParam.ToInt32() & 0xff);
    3.19 +        }
    3.20 +
    3.21 +        public static int GET_APPCOMMAND_LPARAM(IntPtr lParam)
    3.22 +        {
    3.23 +            return ((short)HIWORD(lParam.ToInt32()) & ~Const.FAPPCOMMAND_MASK);
    3.24 +        }
    3.25 +
    3.26 +        public static int GET_DEVICE_LPARAM(IntPtr lParam)
    3.27 +        {
    3.28 +            return ((ushort)(HIWORD(lParam.ToInt32()) & Const.FAPPCOMMAND_MASK));
    3.29 +        }
    3.30 +
    3.31 +        public static int HIWORD(int val)
    3.32 +        {
    3.33 +            return ((val >> 16) & 0xffff);
    3.34 +        }
    3.35 +
    3.36 +
    3.37 +        //#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
    3.38 +        //#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))        
    3.39 +        //#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
    3.40 +        //#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
    3.41 +
    3.42 +        //#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
    3.43 +        //#define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
    3.44 +        //#define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
    3.45 +        //#define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
    3.46 +        //#define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
    3.47 +
    3.48 +    }
    3.49 +
    3.50 +
    3.51 +
    3.52      static partial class Const
    3.53      {
    3.54          /// <summary>
    3.55 +        /// Windows Messages
    3.56 +        /// </summary>
    3.57 +        public const int WM_KEYDOWN = 0x0100;
    3.58 +        public const int WM_APPCOMMAND = 0x0319;
    3.59 +        public const int WM_INPUT = 0x00FF;
    3.60 +
    3.61 +        /// <summary>
    3.62          /// GetRawInputDeviceInfo pData points to a string that contains the device name.
    3.63          /// </summary>
    3.64          public const uint RIDI_DEVICENAME = 0x20000007;
    3.65 @@ -48,6 +100,91 @@
    3.66          public const int RID_INPUT = 0x10000003;
    3.67          public const int RID_HEADER = 0x10000005;
    3.68  
    3.69 +        /// <summary>
    3.70 +        /// Possible value taken by wParam for WM_INPUT.
    3.71 +        /// <para />
    3.72 +        /// Input occurred while the application was in the foreground. The application must call DefWindowProc so the system can perform cleanup.
    3.73 +        /// </summary>
    3.74 +        public const int RIM_INPUT = 0;
    3.75 +        /// <summary>
    3.76 +        /// Possible value taken by wParam for WM_INPUT.
    3.77 +        /// <para />
    3.78 +        /// Input occurred while the application was not in the foreground. The application must call DefWindowProc so the system can perform the cleanup.
    3.79 +        /// </summary>
    3.80 +        public const int RIM_INPUTSINK = 1;
    3.81 +
    3.82 +        /// <summary>
    3.83 +        /// If set, the application command keys are handled. RIDEV_APPKEYS can be specified only if RIDEV_NOLEGACY is specified for a keyboard device.
    3.84 +        /// </summary>        
    3.85 +        public const uint RIDEV_APPKEYS = 0x00000400;
    3.86 +
    3.87 +        /// <summary>
    3.88 +        /// If set, the mouse button click does not activate the other window.
    3.89 +        /// </summary>
    3.90 +	    public const uint RIDEV_CAPTUREMOUSE = 0x00000200;
    3.91 +        
    3.92 +        /// <summary>
    3.93 +        /// If set, this enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal.
    3.94 +        /// Windows XP:  This flag is not supported until Windows Vista
    3.95 +        /// </summary>
    3.96 +	    public const uint RIDEV_DEVNOTIFY = 0x00002000;
    3.97 +
    3.98 +        /// <summary>
    3.99 +        /// 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.
   3.100 +        /// </summary>
   3.101 +        public const uint RIDEV_EXCLUDE = 0x00000010;
   3.102 +
   3.103 +        /// <summary>
   3.104 +        /// 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.
   3.105 +        /// Windows XP:  This flag is not supported until Windows Vista
   3.106 +        /// </summary>
   3.107 +	    public const uint RIDEV_EXINPUTSINK = 0x00001000;
   3.108 +
   3.109 +        /// <summary>
   3.110 +        /// 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.
   3.111 +        /// </summary>
   3.112 +	    public const uint RIDEV_INPUTSINK = 0x00000100;
   3.113 +
   3.114 +	    /// <summary>
   3.115 +	    /// 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.
   3.116 +	    /// </summary>
   3.117 +        public const uint RIDEV_NOHOTKEYS = 0x00000200;
   3.118 +
   3.119 +        /// <summary>
   3.120 +        /// 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.
   3.121 +        /// </summary>
   3.122 +        public const uint RIDEV_NOLEGACY = 0x00000030;
   3.123 +        
   3.124 +        /// <summary>
   3.125 +        /// 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.
   3.126 +        /// </summary>
   3.127 +        public const uint RIDEV_PAGEONLY = 0x00000020;
   3.128 +
   3.129 +	    /// <summary>
   3.130 +        /// 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.
   3.131 +	    /// </summary>
   3.132 +        public const uint RIDEV_REMOVE = 0x00000001;
   3.133 +
   3.134 +        public const int APPCOMMAND_BROWSER_BACKWARD = 1;
   3.135 +        public const int APPCOMMAND_VOLUME_MUTE = 8;
   3.136 +        public const int APPCOMMAND_VOLUME_DOWN = 9;
   3.137 +        public const int APPCOMMAND_VOLUME_UP = 10;
   3.138 +        public const int APPCOMMAND_MEDIA_NEXTTRACK = 11;
   3.139 +        public const int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
   3.140 +        public const int APPCOMMAND_MEDIA_STOP = 13;
   3.141 +        public const int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;
   3.142 +        public const int APPCOMMAND_MEDIA_PLAY = 46;
   3.143 +        public const int APPCOMMAND_MEDIA_PAUSE = 47;
   3.144 +        public const int APPCOMMAND_MEDIA_RECORD = 48;
   3.145 +        public const int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
   3.146 +        public const int APPCOMMAND_MEDIA_REWIND = 50;
   3.147 +        public const int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
   3.148 +        public const int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;
   3.149 +
   3.150 +        public const int FAPPCOMMAND_MASK = 0xF000;
   3.151 +        public const int FAPPCOMMAND_MOUSE = 0x8000;
   3.152 +        public const int FAPPCOMMAND_KEY = 0;
   3.153 +        public const int FAPPCOMMAND_OEM = 0x1000;
   3.154  
   3.155      }
   3.156  
   3.157 @@ -60,7 +197,7 @@
   3.158          [MarshalAs(UnmanagedType.U2)]
   3.159          public ushort usUsage;
   3.160          [MarshalAs(UnmanagedType.U4)]
   3.161 -        public int dwFlags;
   3.162 +        public uint dwFlags;
   3.163          public IntPtr hwndTarget;
   3.164      }
   3.165