Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何注册一个全局热键来表示CTRL+;班次+;(信件)使用WPF和.NET3.5?_C#_.net_Wpf_Windows_Hotkeys - Fatal编程技术网

C# 我如何注册一个全局热键来表示CTRL+;班次+;(信件)使用WPF和.NET3.5?

C# 我如何注册一个全局热键来表示CTRL+;班次+;(信件)使用WPF和.NET3.5?,c#,.net,wpf,windows,hotkeys,C#,.net,Wpf,Windows,Hotkeys,我正在用WPF在C#中构建一个应用程序。我怎样才能绑定到一些钥匙上 另外,如何绑定到?我不确定WPF,但这可能会有所帮助。我使用了中描述的解决方案(当然根据我的需要进行了修改),用于C#Windows窗体应用程序,在Windows中分配一个CTRL-KEY组合以显示C#窗体,它工作得很好(即使在Windows Vista上也是如此)。我希望这会有帮助,祝你好运 John建议的RegisterHotKey()可能有效-唯一的问题是它需要一个HWND(使用PresentationSource.Fro

我正在用WPF在C#中构建一个应用程序。我怎样才能绑定到一些钥匙上


另外,如何绑定到?

我不确定WPF,但这可能会有所帮助。我使用了中描述的解决方案(当然根据我的需要进行了修改),用于C#Windows窗体应用程序,在Windows中分配一个CTRL-KEY组合以显示C#窗体,它工作得很好(即使在Windows Vista上也是如此)。我希望这会有帮助,祝你好运

John建议的RegisterHotKey()可能有效-唯一的问题是它需要一个HWND(使用
PresentationSource.FromVisual()
,并将结果强制转换为HwndSource)


但是,您还需要响应
WM_热键
消息-我不确定是否有办法访问WPF窗口的WndProc(这可以在Windows窗体窗口中完成)。

我不确定您在这里所说的“全局”是什么意思,但它就在这里(我假设您指的是应用程序级别的命令,例如,保存所有可以通过Ctrl+Shift+S从任何位置触发的命令。)

您可以找到您选择的全局
UIElement
,例如,顶层窗口,它是需要此绑定的所有控件的父级。由于WPF事件“冒泡”,子元素上的事件将一直冒泡到控件树的根

现在,首先你需要

  • 使用如下所示的
    InputBinding
    命令绑定键组合
  • 然后,您可以通过
    CommandBinding
    将命令连接到处理程序(例如,
    SaveAll
    调用的代码)
  • 对于Windows键,使用右枚举成员,
    Key.LWin
    Key.RWin

    public WindowMain()
    {
       InitializeComponent();
    
       // Bind Key
       var ib = new InputBinding(
           MyAppCommands.SaveAll,
           new KeyGesture(Key.S, ModifierKeys.Shift | ModifierKeys.Control));
       this.InputBindings.Add(ib);
    
       // Bind handler
       var cb = new CommandBinding( MyAppCommands.SaveAll);
       cb.Executed += new ExecutedRoutedEventHandler( HandlerThatSavesEverthing );
    
       this.CommandBindings.Add (cb );
    }
    
    private void HandlerThatSavesEverthing (object obSender, ExecutedRoutedEventArgs e)
    {
      // Do the Save All thing here.
    }
    

    如果要混合使用Win32和WPF,请看我是如何做到的:

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Interop;
    using System.Windows.Media;
    using System.Threading;
    using System.Windows;
    using System.Windows.Input;
    
    namespace GlobalKeyboardHook
    {
        public class KeyboardHandler : IDisposable
        {
    
            public const int WM_HOTKEY = 0x0312;
            public const int VIRTUALKEYCODE_FOR_CAPS_LOCK = 0x14;
    
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
    
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            private readonly Window _mainWindow;
            WindowInteropHelper _host;
    
            public KeyboardHandler(Window mainWindow)
            {
                _mainWindow = mainWindow;
                _host = new WindowInteropHelper(_mainWindow);
    
                SetupHotKey(_host.Handle);
                ComponentDispatcher.ThreadPreprocessMessage += ComponentDispatcher_ThreadPreprocessMessage;
            }
    
            void ComponentDispatcher_ThreadPreprocessMessage(ref MSG msg, ref bool handled)
            {
                if (msg.message == WM_HOTKEY)
                {
                    //Handle hot key kere
                }
            }
    
            private void SetupHotKey(IntPtr handle)
            {
                RegisterHotKey(handle, GetType().GetHashCode(), 0, VIRTUALKEYCODE_FOR_CAPS_LOCK);
            }
    
            public void Dispose()
            {
                UnregisterHotKey(_host.Handle, GetType().GetHashCode());
            }
        }
    }
    
    您可以在此处获取要注册的热键的虚拟密钥代码:

    也许有更好的办法,但这就是我目前所知道的


    干杯!

    尽管有时RegisterHotKey正是您想要的,但在大多数情况下,您可能不想使用系统范围的热键。我最终使用了如下代码:

    使用System.Windows;
    使用System.Windows.Interop;
    名称空间WpfApp
    {
    公共部分类主窗口:窗口
    {
    常数int WM_KEYUP=0x0101;
    const int VK_RETURN=0x0D;
    const int VK_LEFT=0x25;
    公共主窗口()
    {
    this.InitializeComponent();
    ComponentDispatcher.ThreadPreprocessMessage+=
    组件调度程序线程预处理消息;
    }
    无效组件Dispatcher\u线程预处理消息(
    ref MSG MSG,ref bool(已处理)
    {
    如果(msg.message==WM\u KEYUP)
    {
    if((int)msg.wParam==VK_RETURN)
    MessageBox.Show(“返回被按下”);
    if((int)msg.wParam==VK_左)
    MessageBox.Show(“按下左键”);
    }
    }
    }
    }
    
    这是一个完整的工作解决方案,希望对您有所帮助

    用法:

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

    类别:

    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<int, HotKey> _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<HotKey> Action { get; private set; }
            public int Id { get; set; }
    
            // ******************************************************************
            public HotKey(Key k, KeyModifier keyModifiers, Action<HotKey> 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<int, HotKey>();
                    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
        }
    
        // ******************************************************************
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用系统诊断;
    使用System.Linq;
    使用System.Net.Mime;
    使用System.Runtime.InteropServices;
    使用系统文本;
    使用System.Windows;
    使用System.Windows.Input;
    使用System.Windows.Interop;
    命名空间非托管
    {
    公共类热键:IDisposable
    {
    专用静态字典_dictHotKeyToCalBackProc;
    [DllImport(“user32.dll”)]
    专用静态外部bool寄存器hotkey(IntPtr hWnd、int id、UInt32 fsModifiers、UInt32 vlc);
    [DllImport(“user32.dll”)]
    私有静态外部bool unregister热键(IntPtr hWnd,intid);
    public const int WmHotKey=0x0312;
    private bool_disposed=false;
    公钥{get;private set;}
    public KeyModifier KeyModifier{get;private set;}
    公共操作操作{get;private set;}
    公共int Id{get;set;}
    // ******************************************************************
    公用热键(键k、键修改器、键修改器、动作动作、布尔寄存器=true)
    {
    Key=k;
    KeyModifiers=KeyModifiers;
    行动=行动;
    如果(注册)
    {
    寄存器();
    }
    }
    // ******************************************************************
    公共布尔寄存器()
    {
    int virtualKeyCode=KeyInterop.VirtualKeyFromKey(键);
    Id=virtualKeyCode+((int)键修饰符*0x10000);
    bool result=RegisterHotKey(IntPtr.Zero,Id,(UInt32)键修饰符,(UInt32)虚拟代码);
    如果(_dictHotKeyToCalBackProc==null)
    {
    _dictHotKeyToCalBackProc=新字典();
    ComponentDispatcher.ThreadFilterMessage+=新的ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
    }
    _dictHotKeyToCalBackProc.Add(Id,this);
    Debug.Print(result.ToString()+”、“+Id+”、“+virtualKeyCode”);
    返回结果;
    }
    // ******************************************************************
    公共作废注销()
    {
    热键热键;
    if(_dictHotKeyToCalBackProc.TryGetValue(Id,out热键))
    {
    取消注册热键(IntPtr.Zero,Id);
    }
    }
    // ******************************************************************
    私有静态无效组件DispatcherThreadFilterMessage(ref MSG MSG,ref bool handled)
    {
    如果(!已处理)
    {
    如果(msg.message==WmHotKey)
    {
    热键热键;
    如果(_dictHotKeyToCalBackProc.TryGetValue((
    
    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<int, HotKey> _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<HotKey> Action { get; private set; }
            public int Id { get; set; }
    
            // ******************************************************************
            public HotKey(Key k, KeyModifier keyModifiers, Action<HotKey> 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<int, HotKey>();
                    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
        }
    
        // ******************************************************************
    }
    
    protected override void OnStartup(StartupEventArgs e)
    {
       EventManager.RegisterClassHandler(typeof(Window), Window.PreviewKeyUpEvent, new KeyEventHandler(OnWindowKeyUp));
    }
    
    private void OnWindowKeyUp(object source, KeyEventArgs e))
    {
       //Do whatever you like with e.Key and Keyboard.Modifiers
    }
    
    using System;
    using System.Windows.Forms;
    
    namespace GlobalHotkeyExampleForm
    {
        public partial class ExampleForm : Form
        {
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
            enum KeyModifier
            {
                None = 0,
                Alt = 1,
                Control = 2,
                Shift = 4,
                WinKey = 8
            }
    
            public ExampleForm()
            {
                InitializeComponent();
    
                int id = 0;     // The id of the hotkey. 
                RegisterHotKey(this.Handle, id, (int)KeyModifier.Shift, Keys.A.GetHashCode());       // Register Shift + A as global hotkey. 
            }
    
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
    
                if (m.Msg == 0x0312)
                {
                    /* Note that the three lines below are not needed if you only want to register one hotkey.
                     * The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */
    
                    Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
                    KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
                    int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.
    
    
                    MessageBox.Show("Hotkey has been pressed!");
                    // do something
                }
            }
    
            private void ExampleForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                UnregisterHotKey(this.Handle, 0);       // Unregister hotkey with id 0 before closing the form. You might want to call this more than once with different id values if you are planning to register more than one hotkey.
            }
        }
    }
    
    <KeyBinding Gesture="Ctrl+Alt+Add" Command="{Binding IncrementCommand}" />
    
    <KeyBinding Gesture="Ctrl+Alt+Add" Command="{Binding IncrementCommand}"
                HotkeyManager.RegisterGlobalHotkey="True" />