# 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;
}