2011-11-22 52 views
1

我一直在嘗試在我最新的WPF/C#項目中使用系統範圍/全局熱鍵。對我來說幸運的是,我來到了這個美妙的課堂,在這裏 - http://www.codeproject.com/Tips/274003/Global-Hotkeys-in-WPF試圖在WPF/C中使用(系統範圍)熱鍵#

唯一的問題是,我不能得到它的工作。自從上週以來,我一直在抨擊我的頭腦,奇怪的是,我沒有犯錯。這是我的代碼,任何想法爲什麼?

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; 

在此先感謝!

+0

我已經使用命令和結合的辦法,在這裏一個例子http://stackoverflow.com/questions/2382916/binding-a-wpf-shortcut-key-to-a -command-in-the-viewmodel – kenny

+0

謝謝,但我的意思是全系統的熱鍵。 – mattsven

+0

你使用System.Windows.Input.Key.F2或它的WindowsForms「兄弟」嗎? – Tigran

回答

0

確保您持有對該熱鍵的強烈參考。從您提供的鏈接中,該對象具有一個終結器,它將Enabled設置爲false,這將取消註冊該熱鍵。

+0

請注意,如果這不是問題,請發佈一個更完整的使用片段 - 即您創建熱鍵的位置等。 – AndrewS

1

以下實現使用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; 
} 
} 

處置對象取消註冊熱鍵。 您需要保留對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

好!我有一段時間沒有使用C#,但這看起來很方便。 – mattsven