/// <summary> /// Identifies the handler for a device. /// </summary> /// <param name="lParam">The handle to a raw input dataset.</param> /// <param name="rih">Returns the <see cref="RAWINPUTHEADER"/> of the raw input dataset.</param> /// <returns>The id of the handler.</returns> public T GetHandlerFromWmInput(IntPtr lParam, out RAWINPUTHEADER rih) { rih = RawInput.GetRawInputDataHeader(lParam); T ret; if (!front.TryGetValue(rih.hDevice, out ret)) { return(default(T)); } return(ret); }
/// <summary> /// Enumerate devices and determines the handlers/ids. /// </summary> /// <remarks>To avoid conflicks between threads accessing the object, this method /// should only be call from one thread, maybe in regular intervals (not to short /// ones; maybe every 10 sec). /// </remarks> /// <returns>The number of handled devices.</returns> public int UpdateDevices() { var allDevices = RawInput.EnumerateDevices(); // Remove old entries back.Clear(); // If we find a change, we will swap front and back. bool foundNew = false; // Lock changes to the handlers, while inspecting the devices. lock (handler) { foreach (var device in allDevices) { // Query device info. var deviceInfo = RawInput.GetRawInputDeviceInfo(device.Item1); // If device was known, test it's old handler first. if (front.ContainsKey(device.Item1)) { T id = front[device.Item1]; if (handler.ContainsKey(id) && handler[id](deviceInfo)) { back.Add(device.Item1, id); continue; } } // Find the handler foreach (var idHandler in handler) { if (idHandler.Value(deviceInfo)) { back.Add(device.Item1, idHandler.Key); foundNew = true; break; } } } } // If something changed, swap the dictionaries. if (foundNew || back.Count != front.Count) { back = Interlocked.Exchange(ref front, back); } return(front.Count); }