# HG changeset patch # User sl # Date 1419372323 -3600 # Node ID dd603eba46ca6c7dcd7949da8f6e402e6acae98f # Parent b3e1770628490dff05cfb8461fa6a8820208ae43 Implementing key repeat support. diff -r b3e177062849 -r dd603eba46ca HidEvent.cs --- a/HidEvent.cs Tue Dec 23 21:17:17 2014 +0100 +++ b/HidEvent.cs Tue Dec 23 23:05:23 2014 +0100 @@ -6,6 +6,7 @@ using Microsoft.Win32.SafeHandles; using Win32; using System.Collections.Generic; +using System.Timers; namespace Hid @@ -13,7 +14,7 @@ /// /// Represent a HID event. /// - public class HidEvent + public class HidEvent: IDisposable { public bool IsValid { get; private set; } public bool IsForeground { get; private set; } @@ -29,20 +30,33 @@ public ushort UsagePage { get; private set; } public ushort UsageCollection { get; private set; } public uint UsageId { get { return ((uint)UsagePage << 16 | (uint)UsageCollection); } } - public List Usages { get; private set; } + public List Usages { get; private set; } + public delegate void HidEventRepeatDelegate(HidEvent aHidEvent); + public event HidEventRepeatDelegate OnHidEventRepeat; + private System.Timers.Timer Timer { get; set; } + + + public void Dispose() + { + Timer.Enabled = false; + Timer.Dispose(); + Timer = null; + } /// /// Initialize an HidEvent from a WM_INPUT message /// /// Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as rawinput.header.hDevice - public HidEvent(Message aMessage) + public HidEvent(Message aMessage, HidEventRepeatDelegate aRepeatDelegate) { IsValid = false; IsKeyboard = false; IsGeneric = false; + Timer = new System.Timers.Timer(); Usages = new List(); + OnHidEventRepeat += aRepeatDelegate; if (aMessage.Msg != Const.WM_INPUT) { @@ -175,6 +189,11 @@ Marshal.FreeHGlobal(preParsedData); } + if (Usages[0]!=0) + { + StartRepeatTimer(SystemInformation.KeyboardDelay*250+250); + } + IsValid = true; } @@ -226,7 +245,24 @@ } } + public void StartRepeatTimer(double aInterval) + { + if (Timer == null) + { + return; + } + Timer.Enabled = false; + Timer.AutoReset = false; + Timer.Interval = aInterval; + Timer.Elapsed += (sender, e) => OnRepeatTimerElapsed(sender, e, this); + Timer.Enabled = true; + } + private void OnRepeatTimerElapsed(object sender, ElapsedEventArgs e, HidEvent aHidEvent) + { + StartRepeatTimer(1000/(SystemInformation.KeyboardSpeed+2.5)); + OnHidEventRepeat(aHidEvent); + } } diff -r b3e177062849 -r dd603eba46ca HidHandler.cs --- a/HidHandler.cs Tue Dec 23 21:17:17 2014 +0100 +++ b/HidHandler.cs Tue Dec 23 23:05:23 2014 +0100 @@ -19,18 +19,20 @@ { public delegate void HidEventHandler(object aSender, HidEvent aHidEvent); public event HidEventHandler OnHidEvent; + List iHidEvents; + public bool IsRegistered { get; private set; } public HidHandler(RAWINPUTDEVICE[] aRawInputDevices) { + iHidEvents=new List(); IsRegistered = Function.RegisterRawInputDevices(aRawInputDevices, (uint)aRawInputDevices.Length, (uint)Marshal.SizeOf(aRawInputDevices[0])); } - public void ProcessInput(Message aMessage) { - Hid.HidEvent hidEvent = new Hid.HidEvent(aMessage); + Hid.HidEvent hidEvent = new Hid.HidEvent(aMessage, OnHidEventRepeat); hidEvent.DebugWrite(); if (!hidEvent.IsValid || !hidEvent.IsGeneric) @@ -39,10 +41,36 @@ return; } + // + if (hidEvent.Usages[0] == 0) + { + //This is a key up event + //We need to discard any events belonging to the same page and collection + for (int i = (iHidEvents.Count-1); i >= 0; i--) + { + if (iHidEvents[i].UsageId == hidEvent.UsageId) + { + iHidEvents[i].Dispose(); + iHidEvents.RemoveAt(i); + } + } + } + else + { + //Keep that event until we get a key up message + iHidEvents.Add(hidEvent); + } + //Broadcast our events OnHidEvent(this, hidEvent); } + public void OnHidEventRepeat(HidEvent aHidEvent) + { + //Broadcast our events + OnHidEvent(this, aHidEvent); + } + } } \ No newline at end of file diff -r b3e177062849 -r dd603eba46ca MainForm.cs --- a/MainForm.cs Tue Dec 23 21:17:17 2014 +0100 +++ b/MainForm.cs Tue Dec 23 23:05:23 2014 +0100 @@ -26,6 +26,8 @@ private ColumnHeader columnHeaderUsageCollection; private Timer _timer; + public delegate void OnHidEventDelegate(object aSender, Hid.HidEvent aHidEvent); + public MainForm() { // @@ -152,12 +154,22 @@ { _remote = new RemoteControlDevice(this.Handle); _remote.ButtonPressed += new Devices.RemoteControl.RemoteControlDevice.RemoteControlDeviceEventHandler(_remote_ButtonPressed); - _remote.iHidHandler.OnHidEvent += HandleHidEvent; + _remote.iHidHandler.OnHidEvent += HandleHidEventThreadSafe; } - void HandleHidEvent(object aSender, Hid.HidEvent aHidEvent) + public void HandleHidEventThreadSafe(object aSender, Hid.HidEvent aHidEvent) { - listViewEvents.Items.Insert(0, aHidEvent.ListViewItem); + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe); + this.Invoke(d, new object[] { aSender, aHidEvent }); + } + else + { + //We are in the proper thread + listViewEvents.Items.Insert(0, aHidEvent.ListViewItem); + } } protected override void WndProc(ref Message message) @@ -171,22 +183,24 @@ private bool _remote_ButtonPressed(object sender, RemoteControlEventArgs e) { + //Set text from here was disabled because of threading issues + //That whole thing should be removed anyway bool processed = false; _timer.Enabled = false; if (e.Button != RemoteControlButton.Unknown) { - labelButtonName.Text = e.Button.ToString(); + //labelButtonName.Text = e.Button.ToString(); processed = true; } else if (e.MceButton != Hid.UsageTables.WindowsMediaCenterRemoteControl.Null) { //Display MCE button name - labelButtonName.Text = e.MceButton.ToString(); + //labelButtonName.Text = e.MceButton.ToString(); //Check if this is an HP extension if (Enum.IsDefined(typeof(Hid.UsageTables.HpWindowsMediaCenterRemoteControl), (ushort)e.MceButton)) { //Also display HP button name - labelButtonName.Text += " / HP:" + ((Hid.UsageTables.HpWindowsMediaCenterRemoteControl)e.MceButton).ToString(); + //labelButtonName.Text += " / HP:" + ((Hid.UsageTables.HpWindowsMediaCenterRemoteControl)e.MceButton).ToString(); } processed = true; @@ -194,14 +208,14 @@ else if (e.ConsumerControl != Hid.UsageTables.ConsumerControl.Null) { //Display consumer control name - labelButtonName.Text = e.ConsumerControl.ToString(); + //labelButtonName.Text = e.ConsumerControl.ToString(); processed = true; } else { - labelButtonName.Text = "Unknown"; + //labelButtonName.Text = "Unknown"; } - labelDeviceName.Text = e.Device.ToString(); + //labelDeviceName.Text = e.Device.ToString(); _timer.Enabled = true; return processed; }