Häufig kann man auch ohne globale Hooks auskommen, indem man die RegisterHotkey - API verwendet.
Derlei Registrierungen verhalten sich etwas anders als Hooks, nämlich die TastenKombi wird nur noch ans bei der Registrierung angegebene Handle geschickt, und andere Anwendungen erhalten diesen Tastendruck überhaupt nicht mehr.
Bequemerweise werden bei Freigabe des Handles autom. auch alle seine Hotkey-Registrierungen freigegeben.
Hotkey-Registrierungen sind übrigens der Vorgang im Hintergrund, wenn man im WinExplorer in den Eigenschaften einer Verknüpfung eine TastenKombination festlegt.
Globale Hooks dagegen können ganz im geheimen operieren, und zb. (schlecht gesicherte) Passwort-Eingaben ausspionieren. (Aus dem Grund finde ichs nicht gut, wenn Hook-Code veröffentlicht wird). Ausserdem sind sie komplizierter zu implementieren.
Naja, hier jedenfalls eine kleine Klasse, die eine Tastenkombination mit RegisterHotKey registriert.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace System.Windows.Forms {
public sealed class Hotkey : NativeWindow {
/*zum ID-Parameter: Systemweit kann eine TastenKombi nur einmal registriert werden.
* Also kann man problemlos die Kombi als ihre eigene ID verwenden*/
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int RegisterHotKey(IntPtr Hwnd, int ID, int Modifiers, int Key);
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int UnregisterHotKey(IntPtr Hwnd, int ID);
public event EventHandler Pressed = delegate { };
private int _Value = 0;
private const int _WinKey = (int)Keys.Alt << 1;//die Window-Taste ist nicht Teil der Keys-Enumeration
public Hotkey() { this.CreateHandle(new CreateParams()); }
/// <summary>Registrierung löschen durch Zuweisung von Keys.None</summary>
public Keys Value {
get { return (Keys)_Value; }
set {
if(_Value == (int)value) return;
if(_Value != 0 && UnregisterHotKey(this.Handle, _Value) == 0)
throw new Exception("k.A., was schief läuft");
_Value = (int)value;
if(_Value == 0) return;
var ApiModifier = 0;
if(Keys.Shift == (value & Keys.Shift)) ApiModifier += 4;
if(Keys.Control == (value & Keys.Control)) ApiModifier += 2;
if(Keys.Alt == (value & Keys.Alt)) ApiModifier += 1;
if(_WinKey == (_Value & _WinKey)) ApiModifier += 8;
//Für die API-Registrierung die Keys-Modifier-Komponente (oberhalb 0xffff)
// der Keys-Enumeration wegmaskieren
if(RegisterHotKey(this.Handle, _Value, ApiModifier, _Value & 0xffff) == 0)
throw new Exception("Ist der Key schon von einer anderen Anwendung registriert?");
}
}
protected override void WndProc(ref Message m) {
const int WM_HOTKEY = 0x312;
if(m.Msg == WM_HOTKEY) if(Pressed != null) Pressed(this, EventArgs.Empty);
base.WndProc(ref m);
}
}
}
Der frühe Apfel fängt den Wurm.
Super gute Arbeit!
Das war exakt das was ich gesucht hatte, vielen vielen Dank dafür.
Diese Klasse funktioniert absolut problemlos und bequem.