how to create non window bound keyboard shortcuts

前端 未结 4 1287
故里飘歌
故里飘歌 2021-01-23 10:22

I\'m creating a C# application, could be WinForm, but preferably console application, which needs to capture keyboard shortcuts even when the application is not in the foregroun

4条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-23 10:56

    Here a sample code that I hope would help... (good luck !!!)

    Usage:

                _hotKey0 = new HotKey(Key.F9, KeyModifier.Shift | KeyModifier.Win, OnHotKeyHandler);
    

    ...

            // ******************************************************************
        private void OnHotKeyHandler(HotKey hotKey)
        {
            SystemHelper.SetScreenSaverRunning();
        }
    

    Class:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Net.Mime;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interop;
    
    namespace UnManaged
    {
        public class HotKey : IDisposable
        {
            private static Dictionary _dictHotKeyToCalBackProc;
    
            [DllImport("user32.dll")]
            private static extern bool RegisterHotKey(IntPtr hWnd, int id, UInt32 fsModifiers, UInt32 vlc);
    
            [DllImport("user32.dll")]
            private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            public const int WmHotKey = 0x0312;
    
            private bool _disposed = false;
    
            public Key Key { get; private set; }
            public KeyModifier KeyModifiers { get; private set; }
            public Action Action { get; private set; }
            public int Id { get; set; }
    
            // ******************************************************************
            public HotKey(Key k, KeyModifier keyModifiers, Action action, bool register = true)
            {
                Key = k;
                KeyModifiers = keyModifiers;
                Action = action;
                if (register)
                {
                    Register();
                }
            }
    
            // ******************************************************************
            public bool Register()
            {
                int virtualKeyCode = KeyInterop.VirtualKeyFromKey(Key);
                Id = virtualKeyCode + ((int)KeyModifiers * 0x10000);
                bool result = RegisterHotKey(IntPtr.Zero, Id, (UInt32)KeyModifiers, (UInt32)virtualKeyCode);
    
                if (_dictHotKeyToCalBackProc == null)
                {
                    _dictHotKeyToCalBackProc = new Dictionary();
                    ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
                }
    
                _dictHotKeyToCalBackProc.Add(Id, this);
    
                Debug.Print(result.ToString() + ", " + Id + ", " + virtualKeyCode);
                return result;
            }
    
            // ******************************************************************
            public void Unregister()
            {
                HotKey hotKey;
                if (_dictHotKeyToCalBackProc.TryGetValue(Id, out hotKey))
                {
                    UnregisterHotKey(IntPtr.Zero, Id);
                }
            }
    
            // ******************************************************************
            private static void ComponentDispatcherThreadFilterMessage(ref MSG msg, ref bool handled)
            {
                if (!handled)
                {
                    if (msg.message == WmHotKey)
                    {
                        HotKey hotKey;
    
                        if (_dictHotKeyToCalBackProc.TryGetValue((int)msg.wParam, out hotKey))
                        {
                            if (hotKey.Action != null)
                            {
                                hotKey.Action.Invoke(hotKey);
                            }
                            handled = true;
                        }
                    }
                }
            }
    
            // ******************************************************************
            // Implement IDisposable.
            // Do not make this method virtual.
            // A derived class should not be able to override this method.
            public void Dispose()
            {
                Dispose(true);
                // This object will be cleaned up by the Dispose method.
                // Therefore, you should call GC.SupressFinalize to
                // take this object off the finalization queue
                // and prevent finalization code for this object
                // from executing a second time.
                GC.SuppressFinalize(this);
            }
    
            // ******************************************************************
            // Dispose(bool disposing) executes in two distinct scenarios.
            // If disposing equals true, the method has been called directly
            // or indirectly by a user's code. Managed and unmanaged resources
            // can be _disposed.
            // If disposing equals false, the method has been called by the
            // runtime from inside the finalizer and you should not reference
            // other objects. Only unmanaged resources can be _disposed.
            protected virtual void Dispose(bool disposing)
            {
                // Check to see if Dispose has already been called.
                if (!this._disposed)
                {
                    // If disposing equals true, dispose all managed
                    // and unmanaged resources.
                    if (disposing)
                    {
                        // Dispose managed resources.
                        Unregister();
                    }
    
                    // Note disposing has been done.
                    _disposed = true;
                }
            }
        }
    
        // ******************************************************************
        [Flags]
        public enum KeyModifier
        {
            None = 0x0000,
            Alt = 0x0001,
            Ctrl = 0x0002,
            NoRepeat = 0x4000,
            Shift = 0x0004,
            Win = 0x0008
        }
    
        // ******************************************************************
    }
    

提交回复
热议问题