From b512b6d5a9ac7a50403d7b58037e2934622d1e00 Mon Sep 17 00:00:00 2001 From: Clive Galway Date: Sat, 8 Jun 2019 20:12:37 +0100 Subject: [PATCH] Fix #37 --- .../Helpers/HelperFunctions.cs | 62 +++++++++++----- C#/AutoHotInterception/Manager.cs | 31 ++++---- C#/AutoHotInterception/Monitor.cs | 73 ++++++++++--------- CHANGELOG.md | 2 + 4 files changed, 103 insertions(+), 65 deletions(-) diff --git a/C#/AutoHotInterception/Helpers/HelperFunctions.cs b/C#/AutoHotInterception/Helpers/HelperFunctions.cs index ba13903..1ee4468 100644 --- a/C#/AutoHotInterception/Helpers/HelperFunctions.cs +++ b/C#/AutoHotInterception/Helpers/HelperFunctions.cs @@ -55,29 +55,57 @@ namespace AutoHotInterception.Helpers return stroke; } - public static ButtonState MouseStrokeToButtonState(ManagedWrapper.Stroke stroke) + private static readonly Dictionary ButtonStateLookupTable = new Dictionary() + { + { 1, new ButtonState{Button = 0, State = 1} }, + { 2, new ButtonState{Button = 0, State = 0} }, + { 4, new ButtonState{Button = 1, State = 1} }, + { 8, new ButtonState{Button = 1, State = 0} }, + { 16, new ButtonState{Button = 2, State = 1} }, + { 32, new ButtonState{Button = 2, State = 0} }, + { 64, new ButtonState{Button = 3, State = 1} }, + { 128, new ButtonState{Button = 3, State = 0} }, + { 256, new ButtonState{Button = 4, State = 1} }, + { 512, new ButtonState{Button = 4, State = 0} }, + }; + + public static ButtonState[] MouseStrokeToButtonStates(ManagedWrapper.Stroke stroke) { int state = stroke.mouse.state; - ushort btn = 0; - if (state < 0x400) + + // Buttons + var buttonStates = new List(); + foreach (var buttonState in ButtonStateLookupTable) { - //while (state > 2) - //{ - // state >>= 2; - // btn++; - //} - - //state = 2 - state; // 1 = Pressed, 0 = Released - btn = 0; + if (state < buttonState.Key) break; + if ((state & buttonState.Key) != buttonState.Key) continue; + + buttonStates.Add(buttonState.Value); + state -= buttonState.Key; } - else + + // Wheel + if ((state & 0x400) == 0x400) // Wheel up / down { - if (state == 0x400) btn = 5; // Vertical mouse wheel - else if (state == 0x800) btn = 6; // Horizontal mouse wheel - state = stroke.mouse.rolling < 0 ? -1 : 1; + buttonStates.Add( + new ButtonState + { + Button = 5, + State = (stroke.mouse.rolling < 0 ? -1 : 1) + } + ); } - - return new ButtonState {Button = btn, State = state}; + else if ((state & 0x800) == 0x800) // Wheel left / right + { + buttonStates.Add( + new ButtonState + { + Button = 6, + State = (stroke.mouse.rolling < 0 ? -1 : 1) + } + ); + } + return buttonStates.ToArray(); } public static KeyboardState KeyboardStrokeToKeyboardState(ManagedWrapper.Stroke stroke) diff --git a/C#/AutoHotInterception/Manager.cs b/C#/AutoHotInterception/Manager.cs index a43e973..6b61acc 100644 --- a/C#/AutoHotInterception/Manager.cs +++ b/C#/AutoHotInterception/Manager.cs @@ -609,21 +609,24 @@ namespace AutoHotInterception { // Mouse Button //Debug.WriteLine($"AHK| Mouse {i} seen - flags: {stroke.mouse.flags}, raw state: {stroke.mouse.state}"); - var btnState = MouseStrokeToButtonState(stroke); - if (_mouseButtonMappings[i].ContainsKey(btnState.Button)) + var btnStates = MouseStrokeToButtonStates(stroke); + foreach (var btnState in btnStates) { - hasSubscription = true; - var mapping = _mouseButtonMappings[i][btnState.Button]; - if (mapping.Block) block = true; - - var state = btnState; - - if (mapping.Concurrent) - ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(state.State)); - else if (_workerThreads.ContainsKey(i) && - _workerThreads[i].ContainsKey(btnState.Button)) - _workerThreads[i][btnState.Button]?.Actions - .Add(() => mapping.Callback(state.State)); + if (_mouseButtonMappings[i].ContainsKey(btnState.Button)) + { + hasSubscription = true; + var mapping = _mouseButtonMappings[i][btnState.Button]; + if (mapping.Block) block = true; + + var state = btnState; + + if (mapping.Concurrent) + ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(state.State)); + else if (_workerThreads.ContainsKey(i) && + _workerThreads[i].ContainsKey(btnState.Button)) + _workerThreads[i][btnState.Button]?.Actions + .Add(() => mapping.Callback(state.State)); + } } //Console.WriteLine($"AHK| Mouse {i} seen - button {btnState.Button}, state: {stroke.mouse.state}, rolling: {stroke.mouse.rolling}"); diff --git a/C#/AutoHotInterception/Monitor.cs b/C#/AutoHotInterception/Monitor.cs index 84d8cea..d4d8902 100644 --- a/C#/AutoHotInterception/Monitor.cs +++ b/C#/AutoHotInterception/Monitor.cs @@ -99,6 +99,7 @@ namespace AutoHotInterception while (_pollThreadRunning) { for (var i = 1; i < 11; i++) + { while (ManagedWrapper.Receive(_deviceContext, i, ref stroke, 1) > 0) { ManagedWrapper.Send(_deviceContext, i, ref stroke, 1); @@ -120,51 +121,55 @@ namespace AutoHotInterception Info = stroke.key.code > 255 ? "Extended" : "" }); } + } for (var i = 11; i < 21; i++) + { while (ManagedWrapper.Receive(_deviceContext, i, ref stroke, 1) > 0) { ManagedWrapper.Send(_deviceContext, i, ref stroke, 1); - //if (stroke.mouse.state != 0) - //{ + if (stroke.mouse.state != 0) + { // Mouse Button - var btnState = MouseStrokeToButtonState(stroke); + var btnStates = MouseStrokeToButtonStates(stroke); + foreach (var btnState in btnStates) + { + FireMouseCallback(new MouseCallback + { + Id = i, + Code = btnState.Button, + State = btnState.State, + Info = "Mouse Button" + }); + } + } + else if ((stroke.mouse.flags & (ushort)ManagedWrapper.MouseFlag.MouseMoveAbsolute) == + (ushort)ManagedWrapper.MouseFlag.MouseMoveAbsolute) + { + // Absolute Mouse Move + FireMouseCallback(new MouseCallback + { + Id = i, + X = stroke.mouse.x, + Y = stroke.mouse.y, + Info = "Absolute Move" + }); + } + else if ((stroke.mouse.flags & (ushort)ManagedWrapper.MouseFlag.MouseMoveRelative) == + (ushort)ManagedWrapper.MouseFlag.MouseMoveRelative) + + { + // Relative Mouse Move FireMouseCallback(new MouseCallback { Id = i, - Code = btnState.Button, - State = btnState.State, - Info = "Mouse Button" + X = stroke.mouse.x, + Y = stroke.mouse.y, + Info = "Relative Move" }); - //} - //else if ((stroke.mouse.flags & (ushort) ManagedWrapper.MouseFlag.MouseMoveAbsolute) == - // (ushort) ManagedWrapper.MouseFlag.MouseMoveAbsolute) - //{ - // // Absolute Mouse Move - // FireMouseCallback(new MouseCallback - // { - // Id = i, - // X = stroke.mouse.x, - // Y = stroke.mouse.y, - // Info = "Absolute Move" - // }); - //} - //else if ((stroke.mouse.flags & (ushort) ManagedWrapper.MouseFlag.MouseMoveRelative) == - // (ushort) ManagedWrapper.MouseFlag.MouseMoveRelative) - - //{ - // // Relative Mouse Move - // FireMouseCallback(new MouseCallback - // { - // Id = i, - // X = stroke.mouse.x, - // Y = stroke.mouse.y, - // Info = "Relative Move" - // }); - //} - - //FireMouseCallback(i, stroke); + } } + } Thread.Sleep(10); } diff --git a/CHANGELOG.md b/CHANGELOG.md index 761b5e5..1119208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Deprecated ### Removed ### Fixed +- Fixed issue #37 +When multiple mouse buttons changed state in one update of the mouse, only one event would be fired for one of the buttons ## [0.4.1] - 2019-05-15 ### Fixed