1

I want to allow users to re-assign hotkeys at runtime and am using the Gma.System.MouseKeyHook NuGet package.

Creating new hotkeys at runtime works just fine and dandy but clearing the Action of an already assigned Combination/Sequence (by setting its Action = null) does not remove the original assignment.

Is there some way to do this on a per Combination/Sequence basis? More specifically I want to avoid calling Dispose() on my Hook.GlobalEvents() reference and having to re-initialize the whole systems assignments.

Any help would be greatly appreciated :)

tkefauver
  • 491
  • 5
  • 19

1 Answers1

3

If you want to unsubscribe from keypress event:

_globalHook = Hook.GlobalEvents();

_globalHook.KeyPress += GlobalHookKeyPress; //Subscribe
_globalHook.KeyPress -= GlobalHookKeyPress; //Unsubscribe

Edit:

I understand now that you called OnCombination. After going over the code of this method, you cannot change the combinations list after you created it. Other calls to OnCombination will just add more registrations.

Edit:

Another option is to use reactive extensions:

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reactive.Linq;
using Gma.System.MouseKeyHook;
using MouseKeyHook.Rx;

namespace HotkeyPlay
{
    public partial class Form1 : Form
    {
        private IDisposable _keysObservable;

        public Form1()
        {
            InitializeComponent();

            var triggers = new Trigger[]
            {
                Trigger.On(Keys.H).Alt().Shift()
            };

            _keysObservable =
                Hook
                .GlobalEvents()
                .KeyDownObservable()
                .Matching(triggers)
                .Subscribe((trigger) =>
                 {
                     Debug.WriteLine(trigger.ToString());
                 });
        }

        private void button1_Click(object sender, EventArgs e)
        {
            _keysObservable.Dispose();

            var triggers = new Trigger[]
            {
                Trigger.On(Keys.B).Alt().Shift()
            };

            _keysObservable =
                Hook
                .GlobalEvents()
                .KeyDownObservable()
                .Matching(triggers)
                .Subscribe((trigger) =>
                {
                    Debug.WriteLine(trigger.ToString());
                });
        }
    }
}

Nuget packages:

Install-Package System.Reactive.Linq
Install-Package MouseKeyHook.Rx

MouseKeyHook.Rx is still in pre-release version.

Shay Vaturi
  • 89
  • 1
  • 6
  • Yes that's what I figured out by testing OnCombination. I'm afraid the only reasonable option is to `_globalHook.Dispose()` and re-initialize all my shortcuts which is too much of a headache and probably why most apps require a restart when reassigning shortcuts. – tkefauver Nov 05 '20 at 00:46
  • I added a code example for using reactive extension with dispose. – Shay Vaturi Nov 05 '20 at 08:56
  • Happy to help. If this answer solved your issue, please mark it as accepted. Thank you. – Shay Vaturi Nov 14 '20 at 17:36
  • I did @shayvt but it won't help others because somebody marked this and another question I had about `MouseKeyHook` as closed...this one because my question 'doesn't describe desired behavior' which seems clear enough to me I think... – tkefauver Nov 14 '20 at 18:00
  • Your answer seems to only work with `Combination` triggers but when I use a `Sequence` it only registers the first combination. Is there a way to use this method with a `Sequence`? – tkefauver Nov 14 '20 at 18:06
  • Just an fyi @shayvt I unmarked this as an answer because it doesn't work with sequences...i imagine there's a way to solve this with a linq expression but I can't figure how to Subscribe the sequences. – tkefauver Nov 14 '20 at 22:38