Unregistering hotkeys at runtime with MouseKeyHook

251 Views Asked by At

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 :)

1

There are 1 best solutions below

6
Shay Vaturi On

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.