/// <summary> /// Callback function called by the operating system when a keyboard message is processed. /// This function adds data relative to the keyboard message to the <see cref="m_HookQueue"/> queue. /// </summary> /// <param name="nCode">A code the hook procedure uses to determine how to process the message. /// If nCode is less than zero, the hook procedure must pass the message to the <see cref="CallNextHookEx(IntPtr, int, int, IntPtr)"/> /// function without further processing and should return the value returned by <see cref="CallNextHookEx(IntPtr, int, int, IntPtr)"/>.</param> /// <param name="wParam">The identifier of the keyboard message.</param> /// <param name="lParam">A pointer to a <see cref="KBDLLHOOKSTRUCT"/> structure.</param> /// <returns>If returns <see cref="IntPtr.Zero"/> other message hooks in the queue are not processed, /// otherwise processing continues normally.</returns> private IntPtr HookCallBack(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) { KeyData data = new KeyData((User32Helper.WM)wParam.ToInt32(), lParam); m_HookQueue.Add(data); } return(User32Helper.CallNextHookEx(m_HookID, nCode, wParam, lParam)); }
/// <summary> /// This method runs in a separateed thread and takec care to process the generated keyboard messages firing /// <see cref="KeyStatusChanged"/> event according with defined <see cref="Filters"/>. /// </summary> private void Worker() { while (true) { KeyData data = m_HookQueue.Take(); if (data == null) { return; } data.FormatData(); if ((Filters.Count(f => f.CanCombine) == 0 || Filters.Where(f => f.CanCombine).Any(f => f.Apply(data))) && Filters.Where(f => !f.CanCombine).All(f => f.Apply(data))) { KeyStatusChanged?.Invoke(data); } } }