密钥组合快捷方式

时间:2017-07-27 10:38:57

标签: c# wpf keyboard-shortcuts

我正在创建一个WPF应用程序,我有三个窗口(MainWindow, SecondWindow and CameraWindow)。我添加了快捷方式("m")以将相机设置为图像模式。当CameraWindow处于活动状态时,此方法正常。

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    var key = e.Key.ToString().ToLower();
    if (key.Contains("m"))
    {              
       camera.SetImageMode();                
    }
}

我正在寻找在我的应用程序中的任何地方将相机设置为图像模式的方法。我的意思是我应该可以从任何地方将相机设置为图像模式,即使CameraWindow没有激活。

Ctrl + M 可能是组合键。

欢迎任何建议!

2 个答案:

答案 0 :(得分:0)

public class KeyboardHandler : IDisposable
    {
        private readonly int _modKey;
        private const int WmHotkey = 0x0312;
        private readonly WindowInteropHelper _host;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);


        private readonly ISubject<Unit> _hotKeyHandleSubject = new Subject<Unit>();
        public IObservable<Unit> WhenHotKeyHandled { get { return _hotKeyHandleSubject.AsObservable(); } }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mainWindow">the handle to the main window</param>
        /// <param name="vkKey">the virtual key you need to press -> https://msdn.microsoft.com/en-us/library/ms927178.aspx </param>
        /// <param name="modKey">the modifier key you need to press (2 is CTRL by Default) -> https://msdn.microsoft.com/it-it/library/windows/desktop/ms646279(v=vs.85).aspx </param>
        public KeyboardHandler(Window mainWindow, int vkKey, int modKey = 2)
        {
            _modKey = modKey;
            _host = new WindowInteropHelper(mainWindow);

            SetupHotKey(_host.Handle, vkKey);
            ComponentDispatcher.ThreadPreprocessMessage += ComponentDispatcher_ThreadPreprocessMessage;
        }

        private void ComponentDispatcher_ThreadPreprocessMessage(ref MSG msg, ref bool handled)
        {
            if (msg.message == WmHotkey)
            {
                _hotKeyHandleSubject.OnNext(Unit.Default);
            }
        }

        private void SetupHotKey(IntPtr handle, int vkKey)
        {
            RegisterHotKey(handle, GetType().GetHashCode(), _modKey, vkKey);
        }

        public void Dispose()
        {
            ComponentDispatcher.ThreadPreprocessMessage -= ComponentDispatcher_ThreadPreprocessMessage;
            UnregisterHotKey(_host.Handle, GetType().GetHashCode());
        }
    }

像这样使用它:

_keyboardHandler = new KeyboardHandler(this, 0x4D);
            _disposable = _keyboardHandler.WhenHotKeyHandled.ObserveOn(SynchronizationContext.Current).Subscribe(_ =>
            {
                TextBlock.Text += new Random().Next(10) + "_";
            });

感谢https://stackoverflow.com/a/1960122/2159837,我只是修改了一下

如果您的应用程序没有焦点,这也适用

答案 1 :(得分:0)

经过长时间的搜索和实验,终于找到了解决方案 https://stackoverflow.com/a/12676910/8152725