كيف يمكنني التسجيل الساخنة العالمية الرئيسية القول CTRL+SHIFT+(الرسالة) باستخدام WPF و .NET framework 3.5?

StackOverflow https://stackoverflow.com/questions/48935

سؤال

أنا بناء التطبيق في C# باستخدام WPF.كيف يمكنني ربط بعض المفاتيح ؟

أيضا كيف يمكنني ربط مفتاح ويندوز?

هل كانت مفيدة؟

المحلول

أنا لست متأكدا من ماذا تقصد ب "العالمية" هنا, ولكن هنا يذهب (أفترض أنك تعني القيادة على مستوى التطبيق ، على سبيل المثال ، حفظ جميع التي يمكن تشغيلها من أي مكان عن طريق Ctrl + التحول + S.)

تجد العالمية UIElement من اختيارك ، على سبيل المثال ، في إطار المستوى الأعلى الذي هو الأصل من كل الضوابط حيث تحتاج هذه الملزمة.بسبب "محتدما" WPF الأحداث والمناسبات في الطفل عناصر فقاعة كل وسيلة تصل إلى جذر شجرة التحكم.

الآن تحتاج أولا

  1. إلى ربط مفتاح التحرير والسرد مع الأوامر باستخدام InputBinding مثل هذا
  2. ثم يمكنك هوكوب الأمر إلى معالج الخاص بك (على سبيل المثالالتعليمات البرمجية التي يتم استدعاؤها من قبل SaveAll) عبر CommandBinding.

عن ويندوز الرئيسية, يمكنك استخدام الحق الرئيسية تعداد الأعضاء ، Key.LWin أو Key.RWin

    public WindowMain()
    {
       InitializeComponent();
       // Bind Key
       InputBinding ib = new InputBinding(
           MyAppCommands.SaveAll,
           new KeyGesture(Key.S, ModifierKeys.Shift | ModifierKeys.Control));
       this.InputBindings.Add(ib);
       // Bind handler
       CommandBinding 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.
    }

نصائح أخرى

هذا هو العمل الكامل الحل ، نأمل أن يساعد...

الاستخدام:

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

...

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

الدرجة:

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
    }

    // ******************************************************************
}

إذا كنت تريد الذهاب إلى مزيج 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());
        }
    }
}

يمكنك الحصول على الظاهري مفتاح رمز اختصار تريد التسجيل من هنا: http://msdn.microsoft.com/en-us/library/ms927178.aspx

قد يكون هناك طريقة أفضل, ولكن هذا ما لدي حتى الآن.

هتاف!

تسجيل مستوى نظام التشغيل اختصارات لا يكاد أي وقت مضى شيء جيد:المستخدمين لا تريد أن تعبث مع نظام التشغيل الخاصة بهم.

وقال أن هناك أبسط من ذلك بكثير و سهل الاستعمال طريقة للقيام بذلك في WPF, إذا كنت موافق مع هوتكي العمل داخل التطبيق فقط (أنا.هـ طالما WPF التطبيق لديه التركيز):

في التطبيق.xaml.cs :

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.
        }
    }
}

لقد وجدت أنه على fluxbytes.com.

على الرغم من أن RegisterHotKey في بعض الأحيان بالضبط ما تريد, في معظم الحالات ربما لا تريد استخدام على نطاق المنظومة مفاتيح الاختصار.انتهى بي الأمر باستخدام التعليمات البرمجية كما يلي:

using System.Windows;
using System.Windows.Interop;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        const int WM_KEYUP = 0x0101;

        const int VK_RETURN = 0x0D;
        const int VK_LEFT = 0x25;  

        public MainWindow()
        {
            this.InitializeComponent();

            ComponentDispatcher.ThreadPreprocessMessage += 
                ComponentDispatcher_ThreadPreprocessMessage;
        }

        void ComponentDispatcher_ThreadPreprocessMessage(
            ref MSG msg, ref bool handled)
        {
            if (msg.message == WM_KEYUP)
            {
                if ((int)msg.wParam == VK_RETURN)
                    MessageBox.Show("RETURN was pressed");

                if ((int)msg.wParam == VK_LEFT)
                    MessageBox.Show("LEFT was pressed");
            }
        }
    }
}

أنا غير متأكد حول WPF, ولكن هذا قد يساعد.أنا استخدم الحل هو موضح في RegisterHotKey (user32) (تعديل احتياجات بلدي بالطبع) في C# تطبيق نماذج Windows تعيين CTRL-تركيبة المفاتيح في ويندوز إحضار C# نموذج وانها عملت بشكل جميل (حتى على ويندوز فيستا).وآمل أن يساعد وحظا سعيدا!

لقد وجدت العالمية مفاتيح الاختصار في WPF مشروع codeproject.com التي لا وظيفة لي.انها حديثة نسبيا ، لا حاجة إلى الإشارة إلى النظام.يقوم نظام ويندوز.أشكال يعمل "عالميا" من حيث الرد على مفتاح التشغيل يتم الضغط عليه حتى لو كان "إعدادات" التطبيق هو الإطار النشط.

RegisterHotKey() اقترح جون يمكن أن تعمل - الصيد الوحيد هو أنه يتطلب HWND (باستخدام PresentationSource.FromVisual(), و صب النتيجة إلى HwndSource).

ومع ذلك ، سوف تحتاج أيضا إلى الاستجابة WM_HOTKEY رسالة - لست متأكدا إذا كان هناك طريقة للحصول على الوصول إلى WndProc من نافذة WPF أو لا (الذي يمكن القيام به للحصول على نماذج Windows في نظام التشغيل windows).

البابون هو الحل الأفضل لأنه قد يكون لديك العديد من النوافذ.لم قرص من ذلك فإنه يستخدم PreviewKeyDownEvent بدلا من PreviewKeyUpEvent من أجل التعامل مع التكرار في ضربات المفاتيح.

أنصح ضد نظام التشغيل على مستوى التسجيل إلا إذا كنت تكتب شيئا مثل أداة القص أو تسجيل صوتي التطبيق لأنها سوف تتيح لك الوصول إلى الوظيفة عند النافذة لا يركز.

زميل كتب عينة عن كيفية إنشاء لوحة المفاتيح ذات المستوى المنخفض هوك ليتم استخدامها مع برنامج الأغذية العالمي.

http://blogs.vertigo.com/personal/ralph/Blog/Lists/Posts/Post.aspx?ID=8

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top