Попытка использовать (общесистемные) горячие клавиши в WPF / C # - PullRequest
2 голосов
/ 23 ноября 2011

Я пытался использовать общесистемные / глобальные горячие клавиши в моем последнем проекте WPF / C #. К счастью для меня, я наткнулся на этот замечательный класс, здесь - http://www.codeproject.com/Tips/274003/Global-Hotkeys-in-WPF.

Единственная проблема в том, Я не могу заставить его работать . Я бился головой с этим с прошлой недели, и странно то, что я не получаю ошибок. Вот мой код, есть идеи, почему?

HotKey hotkey = new HotKey((System.Windows.Interop.HwndSource)System.Windows.Interop.HwndSource.FromVisual(App.Current.MainWindow));
                //hotkey.Modifiers = list[i]._HotkeyA.Modifier; hotkey.Key = list[i]._HotkeyA._Key;
                hotkey.Modifiers = HotKey.ModifierKeys.Shift; hotkey.Key = Key.F2;
                hotkey.HotKeyPressed += new EventHandler<HotKeyEventArgs>(delegate(Object o, HotKeyEventArgs e)
                {
                    Console.WriteLine("Congratulations, Cap'n.");
                    System.Windows.Forms.MessageBox.Show("YAAY HOTKEY HAZ BEEN TEH PRESSEDS!");
                });
                hotkey.Enabled = true;

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 26 сентября 2015

Следующая реализация использует класс WPF ComponentDispatcher для отправки сообщений Windows.

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

[Flags]
public enum ModifierKeyCodes : uint
{
    Alt = 1,
    Control = 2,
    Shift = 4,
    Windows = 8
}

/// <summary>
/// Virtual Key Codes
/// </summary>
public enum VirtualKeyCodes : uint
{
A = 65,
B = 66,
C = 67,
D = 68,
E = 69,
F = 70,
G = 71,
H = 72,
I = 73,
J = 74,
K = 75,
L = 76,
M = 77,
N = 78,
O = 79,
P = 80,
Q = 81,
R = 82,
S = 83,
T = 84,
U = 85,
V = 86,
W = 87,
X = 88,
Y = 89,
Z = 90
}

class KeyboardHook : IDisposable
{
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeyCodes fdModifiers, VirtualKeyCodes vk);

#region Fields
WindowInteropHelper host;
bool IsDisposed = false;
int Identifier;

public Window Window { get; private set; }

public VirtualKeyCodes Key { get; private set; }

public ModifierKeyCodes Modifiers { get; private set; }
#endregion

public KeyboardHook(Window Window, VirtualKeyCodes Key, ModifierKeyCodes Modifiers)
{
    this.Key = Key;
    this.Modifiers = Modifiers;

    this.Window = Window;
    host = new WindowInteropHelper(Window);

    Identifier = Window.GetHashCode();

    RegisterHotKey(host.Handle, Identifier, Modifiers, Key);

    ComponentDispatcher.ThreadPreprocessMessage += ProcessMessage;
}

void ProcessMessage(ref MSG msg, ref bool handled)
{
    if ((msg.message == 786) && (msg.wParam.ToInt32() == Identifier) && (Triggered != null))
        Triggered();
}

public event Action Triggered;

public void Dispose()
{
    if (!IsDisposed)
    {
        ComponentDispatcher.ThreadPreprocessMessage -= ProcessMessage;

        UnregisterHotKey(host.Handle, Identifier);
        Window = null;
        host = null;
    }
    IsDisposed = true;
}
}

Удаление объекта Отменяет регистрацию HotKey.Вам необходимо сохранить ссылку на класс KeyboardHook, чтобы предотвратить его незарегистрированность.

Пример:

// Registers a Hook to MyWindow - Ctrl+A and calls DoWork() when Triggered.
var KH = new KeyboardHook(MyWindow, VirtualKeyCodes.A, ModifierKeyCodes.Ctrl);
KH += () => DoWork();

// When you don't need the Hook
KH.Dispose();
0 голосов
/ 23 ноября 2011

Убедитесь, что вы держите сильную ссылку на этот HotKey.По предоставленной вами ссылке у этого объекта есть финализатор, который установит для параметра Enabled значение false, что приведет к отмене регистрации горячей клавиши.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...