Git Product home page Git Product logo

nhotkey's Introduction

NHotkey

NuGet version NuGet version NuGet version AppVeyor build

Easily handle shortcut keys even when your WPF or WinForms app doesn't have focus. Declare hotkeys in XAML with the familiar KeyBinding syntax.

Nuget packages:

Windows Forms usage

Add a reference to NHotkey.dll and NHotkey.WindowsForms.dll. In the file where you want to handle hotkeys, import the NHotkey.WindowsForms namespace:

    using NHotkey.WindowsForms;

During initialization, add some hotkeys:

    HotkeyManager.Current.AddOrReplace("Increment", Keys.Control | Keys.Alt | Keys.Add, OnIncrement);
    HotkeyManager.Current.AddOrReplace("Decrement", Keys.Control | Keys.Alt | Keys.Subtract, OnDecrement);
  • the first parameter is an application-defined name for the hotkey; it can be anything you like, as long as it's unique;
  • the second parameter is the combination of keys for which you want to register a hotkey;
  • the last parameter is a delegate of type EventHandler<HotkeyEventArgs> that will be called when this hotkey is pressed. For instance:
    private void OnIncrement(object sender, HotkeyEventArgs e)
    {
        Value++;
        e.Handled = true;
    }

    private void OnDecrement(object sender, HotkeyEventArgs e)
    {
        Value--;
        e.Handled = true;
    }

If you want to handle several hotkeys with the same handler, you can check the Name property of the HotkeyEventArgs:

    private void OnIncrementOrDecrement(object sender, HotkeyEventArgs e)
    {
        switch (e.Name)
        {
            case "Increment":
                Value++;
                break;
            case "Decrement":
                Value--;
                break;
        }
        e.Handled = true;
    }

WPF usage

The approach for WPF is very similar to the one for Windows Forms; the exposed API is slightly different to account for the differences between WinForms and WPF. The WPF version also supports KeyBindings.

Add a reference to NHotkey.dll and NHotkey.Wpf.dll. In the file where you want to handle hotkeys, import the NHotkey.Wpf namespace:

    using NHotkey.Wpf;

During initialization, add some hotkeys:

    HotkeyManager.Current.AddOrReplace("Increment", Key.Add, ModifierKeys.Control | ModifierKeys.Alt, OnIncrement);
    HotkeyManager.Current.AddOrReplace("Decrement", Key.Subtract, ModifierKeys.Control | ModifierKeys.Alt, OnDecrement);
  • the first parameter is an application-defined name for the hotkey; it can be anything you like, as long as it's unique;
  • the second and third parameters are the key and modifiers for which you want to register a hotkey;
  • the last parameter is a delegate of type EventHandler<HotkeyEventArgs> that will be called when this hotkey is pressed.

To support applications that use the MVVM pattern, you can also specify hotkeys in XAML using InputBindings. Just declare KeyBindings as usual, and set the HotkeyManager.RegisterGlobalHotkey attached property to true:

    ...
    <Window.InputBindings>
        <KeyBinding Gesture="Ctrl+Alt+Add" Command="{Binding IncrementCommand}"
                    HotkeyManager.RegisterGlobalHotkey="True" />
        <KeyBinding Gesture="Ctrl+Alt+Subtract" Command="{Binding DecrementCommand}"
                    HotkeyManager.RegisterGlobalHotkey="True" />
    </Window.InputBindings>
    ...

Known limitations of this feature

  • the HotkeyManager can't detect if you remove a KeyBinding; it only relies on the attached property being set to true or false. If you want to remove a KeyBinding at runtime, make sure you set HotkeyManager.RegisterGlobalHotkey to false, otherwise it will still be registered
  • changing the keys or modifiers of a KeyBinding at runtime is currently not supported. If you need to modify a KeyBinding at runtime, you need to set HotkeyManager.RegisterGlobalHotkey to false, change the key, and set HotkeyManager.RegisterGlobalHotkey to true again.

nhotkey's People

Contributors

ihsansfd avatar thomaslevesque avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nhotkey's Issues

Not working

I tried to use this library in VB.Net but it does not register hotkeys. Here is the relevant code.

Dim hk = Keys.ControlKey Or Keys.H

Dim hh = Sub(s, e)
             MsgBox("HIT")
             e.Handled = True
        End Sub

NHotkey.WindowsForms.HotkeyManager.Current.AddOrReplace("WinToggle", hk, hh)

NHotkey and WinUI 3

Hello,
I have a project that uses WinForms and heavily uses NHotkey. We would like to port this project to the new WinUI 3, but global hotkeys is a must. Will NHotkey be able to use WinUI 3, like it does WPF?

Single Press

Hi,

I have registered Alt A perfectly.
But when i press alt-a, that hotkey function runs many times if i press little longer.

Is there a way to handle hotkey once? I mean keeping pressed to alt-a should run handler function just once.

Thanks

Binding The Escape Key Non-Exclusively

I am binding an event to the Escape key, but when I do that other applications (such as Window's Snap Assist) no longer gets the event. Is there any way to bind the event and still allow other things to receive the event?

HotkeyEventArgs.Handled property not passing through keys

Regardless of whether the HotkeyEventArgs.Handled property is set to true or false, the key is being blocked.

What I am trying to do is limit the hotkey to certain windows.. if its not a window that I recognize, I set the handled property to false. I would expect this to allow the key to passthru to the unrecognized window. This is not the case.

Example:

            HotkeyManager.Current.AddOrReplace("RotateLeft", Key.Left, ModifierKeys.None, (sender, e) =>
            {
                if (HotkeyWindow.ActiveWindowSupported())
                    {
                          OnRotateHotkey(sender, e);
                          e.Handled = true;
                    }
                else
                    e.Handled = false;
            });

Assemblies are not Strong Named

Hi,

I am unable to use this library as it is not strong named. Is it possible for you to publish a strong named version or strong name the package by default?

Respond only within the current program

How do I enable shortcuts while limiting the response to the current program, rather than the entire Windows system?

My environment is WinFRM, and the effect I want is to press a shortcut key to open a specified form.

Override already existing hotkey?

Is there a way to override a global hotkey that is already registered in the system? For example, if I wanted to change Ctrl + V to something else that I handle in code would I be able to do that somehow?

how to not Disable System Work

I set an hot key on space (and other keys) and every now space works nowhere. how to make it work in other programs?
(I use NHotKey for a trick. to get keys while focused on VLC video view.)
I disabled hotkey action in my app with checking window.IsActive but I want keys work else where.

IntPtr activeWinHwnd = GetActiveWindow();
Window win = Window.GetWindow(this);
Window win2 = Window.GetWindow(InPlayerBrd);
if (!win.IsActive && !win2.IsActive && activeWinHwnd != MediaPlayer.Hwnd)
    return;

How to conditionally handle key

I've tried setting .Handled = false but it doesn't seem to have any effect. I would like to only intercept the hotkey if certain conditions are met. Not sure if this is even possible with WinAPI, any help would be appreciated thanks

Document limitations

Users often open issues about being unable to register certain key combinations.
Most of these are limitations of the RegisterHotKey API.
They should be mentioned in the README.

PTT (Press To Talk) function?

I need to implement a PTT Press To Talk , function in my app..

That is i need to do something while the key is pressed. Is there any way to do that with this library?

As i see the library is detecting the key when it is released.

Any ideas?

Other applications in "thinking state" blocking global hotkeys

Hi!
I use your great library to open a window whenever needed.
The only limitation I found so far is, whenever I have focused on an app that is currently performing some freezing calculating (the kind where you click the window, it gets white and asks if you want to wait) the global hotkeys are not responsible.
Have you ever had such a situation?
I figured that when pressing win+b to focus the systray, (or win+t taskbar) it happens right away (even if active app freezes) and from there I could press my hotkeys.

How to bind global key without key modifier?

I writing a software that I would like to invoke my software when user press backtick key, HotkeyManager.Current.AddOrReplace require the KeyModifier , is it possible to bind single key short-cut with NHotkey?

How to make a local HotkeyManager

Hi,

I am trying to use your library to implement a set of Hotkeys, but I am encountering a problem.

My application contains 2 windows, namely Window A and Window B, and Window A and Window B have a different set of hotkeys, which some of them might be overlapping.

My question is how to implement or config NHotkey to execute hotkeys based on focused windows.

Thanks.

How i can SendKeys to window, without infinity iteration?

I use your beautiful library, but, when i check clicking on e.g F9, and Send key to another window (e.g F9) - i get infinity iteration :D

i.e if i click F9 and if i send key F9 i get infinity iteration.

                if (e.Name == "F9")
                {
                    IntPtr sacredhandle = FindWindow("Sacred", "Sacred");

                    SetForegroundWindow(sacredhandle);

                    SendKeys.SendWait(HotkeySettings.GameHotkeySettings.KeyF9); // e.g F9 

                    AppLogger.Log.Info($"Key {HotkeySettings.GameHotkeySettings.KeyF9} successfully sended to Sacred.exe window");

                    e.Handled = true;
                }

or : if i click on Z (Z emulate clicking F9), - i also get infinity iteration.

                if (e.Name == "Z")
                {
                    IntPtr sacredhandle = FindWindow("Sacred", "Sacred");

                    SetForegroundWindow(sacredhandle);

                    SendKeys.SendWait(HotkeySettings.GameHotkeySettings.KeyZ); // e.g also F9 

                    AppLogger.Log.Info($"Key {HotkeySettings.GameHotkeySettings.KeyZ} successfully sended to Sacred.exe window");

                    e.Handled = true;
                }

Also clicking on Z, lib think what i clicking on F9, and ... infinity iteration :D

The NHotKey.HotKeyAlreadyRegisteredException exception seems to be non-implemented

Hi, I had a particular need to check programmatically at runtime whether or not a particular keyboard shortcut already exists, in a utility I am developing that allows users to create keyboard shortcuts (obviously I want to check so that if the user says, for example, create a keyboard shortcut using Ctrl-J, but there is already a defined/active keyboard shortcut that uses Ctrl-J, I tell them "sorry, there is already a keyboard shortcut using Ctrl-J, specify different keys for your shortcut".

So I came across this package and I love how easy it is to define keyboard shortcuts, very slick and concise. However, I saw that there were two things in the package:

  1. In the second overload of the AddOrReplace method, there is a 3rd parameter, bool noRepeat.
  2. There is an exception, NHotKey.HotKeyAlreadyRegisteredException, which is defined.

So I was expecting to be able to utilize these constructs to do what I needed (check for pre-existence of a keyboard shortcut). But in a test program (visual studio 2017 solution attached in a zip file), it seemed as if the noRepeat parameter being true or false made no difference, and I didn't see how to make use of the HotKeyAlreadyRegisteredException exception (if those 2 things are even related to each other).

Are these features not fully implemented, or if so, can you clarify how to make use of them? ... and/or address the general question of whether it is possible to check for the existence of a particular keyboard shortcut before creating it.

TIA

WindowsFormsApp1V472.zip

Exception when setting global hotkey during handling of event in WPF

Hey,

I have a case in my application where I want to make a KeyBinding global or not global depending on a state in the application. So whenever a certain event is triggered I use HotkeyManager.SetRegisterGlobalHotkey(...) to enable/disable the KeyBinding being global. But if this happens in the same time when a KeyBinding is currently handled I get the following exception:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at NHotkey.Wpf.WeakReferenceCollection`1.<GetEnumerator>d__1.MoveNext() in C:\projects\nhotkey\src\NHotkey.Wpf\WeakReferenceCollection.cs:line 14
   at NHotkey.Wpf.HotkeyManager.ExecuteBoundCommand(Hotkey hotkey) in C:\projects\nhotkey\src\NHotkey.Wpf\HotkeyManager.cs:line 195
   at NHotkey.Wpf.HotkeyManager.HandleMessage(IntPtr hwnd, Int32 msg, IntPtr wparam, IntPtr lparam, Boolean& handled) in C:\projects\nhotkey\src\NHotkey.Wpf\HotkeyManager.cs:line 185
   at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Hot key is already registered error in RegisterGlobalHotkey

System.Windows.Markup.XamlParseException was unhandled
HResult=-2146233087
Message=’Set property ‘NHotkey.Wpf.HotkeyManager.RegisterGlobalHotkey’ threw an exception.’ Line number ’19′ and line position ’61′.

HResult=-2147023487
Message=Hot key is already registered. (Exception from HRESULT: 0×80070581)
Source=NHotkey
ErrorCode=-2147023487

Please don't make the HotkeyEventArgs's constructor internal

I'm about to unit test this class until I know that the HotkeyEventArg's constructor is set to internal. This makes it such a pain to unit test. Please fix this. Or at the very least if you still want to make it internal, provide public factory that everyone can access.

Btw, great library!

Cannot add F12 as hotkey without modifiers

Using NHotkey.Wpf I cannot add F12 as a hotkey without modifiers. If I try I get NHotkey.HotkeyAlreadyRegisteredException: 'Hot key is already registered.

While this works:
HotkeyManager.Current.AddOrReplace("Increment", new KeyGesture(Key.F12, ModifierKeys.Alt), OnIncrement);

This throws the exception:
HotkeyManager.Current.AddOrReplace("Increment1", new KeyGesture(Key.F12, ModifierKeys.None), OnIncrement);
throws exception

And even more confusing, this works too:
HotkeyManager.Current.AddOrReplace("Increment2", new KeyGesture(Key.F11, ModifierKeys.None), OnIncrement);

I expected (maybe I am mistaken) that if defining a KeyGesture for a Key (with or without modifiers) is legal, setting it as a hotkey should be, too.

Can't Run Hotkeys Asynchronously

I have two hotkeys set, one to perform an action and the other to cancel it. The problem is that when I call the second hotkey while the first hotkey is doing something, it doesn't trigger until after the first one is done.

HotkeyManager.Current.AddOrReplace("Paste", HkTextBox.Hotkey.Key, HkTextBox.Hotkey.Modifiers, AutoPaste);
HotkeyManager.Current.AddOrReplace("CancelPaste", Key.Escape, ModifierKeys.Alt, CancelPaste);

need help defining multiple hotkeys

Hello,
I'm fairly new to c#. My application needs to define multiple hotkeys, which are being read from an ini file.
The ini file format for a key looks like this:
director_key = 2,49
This would be ctrl+f.
When I try to pass the key 49, and the modifier 2 (ctrl), I get the following error:
Error CS1503 Argument 2: cannot convert from 'string' to 'System.Windows.Input.KeyGesture'
I'm sure there's something relatively simple I'm missing here, I just can't quite figure this out.
I'm defining all the keys in a foreach loop that steps through my ini file.

shortcut of win key + regular key throw exception

I am trying to register to the hotkey with Key (for example) 'Z' and modifier as "Windows" .
When I register for the first time, I get this exception:

NHotkey.HotkeyAlreadyRegisteredException: 'Hot key is already registered. (Exception from HRESULT: 0x80070581)'

Inner exception:
COMException: Hot key is already registered. (Exception from HRESULT: 0x80070581)

Windows with other modifier (for instance; ctrl+windows+z) works fine.

This is WPF application.

Commands.XmlSerializers

Everything worked fine, but now I get Exception
"A first chance exception of type 'System.IO.FileNotFoundException' occurred in NHotkey.dll ... couldnt load assembly "Commands.XmlSerializers" "
On this line of code:
HotkeyManager.Current.AddOrReplace("Invisible", Key.Subtract, ModifierKeys.Control | ModifierKeys.Alt, OnInvisible);

storing keys in xml settings file

Hello!
Do you have any code examples for reading/writing hotkey values from a .net settings file? Just not sure how to best represent them in the file, then read them in and register them when the app starts. I was initially using WPF, but I've since switched to Winforms for various reasons.
Thanks!

Global Hot Key can't bring the window back to front if the app is in system tray

I tried your project with "Hardcodet NotifyIcon for WPF" - at the moment no .Net Core support. I tried with .NET Framework 4.7.2.

GitHub: https://github.com/hardcodet/wpf-notifyicon

Project Site: http://www.hardcodet.net/wpf-notifyicon

I tried the "Windowless Sample". If the app is in system tray the global hot key can't bring the window back to front.

this.WindowState = WindowState.Normal;
this.Activate();
// this.Topmost = true;
// this.Topmost = false;
this.Focus();

Any ideas how I can achieve this?

Support for multiple key gestures

As in Visual Studio, Ctrl+W,S shows Solution Explorer. Ctrl+K,Ctrl+D formats the document.

It would be nice NHotKey to support these combinations. This article shows how this can be done in WPF with InputGestures, but it's not production ready.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.