2013-08-17 12 views
11

Ich versuche, die Print Screen Schaltfläche zu drücken, während das Formular nicht die aktuelle aktive Anwendung ist.Wie erkenne ich keyPress, wenn nicht fokussiert?

Wie geht das, wenn möglich?

+0

Sieht aus wie es helfen kann: http://social.msdn.microsoft.com/Forums/ de-DE/94b1598f-79ce-4c70-8851-86aff6d9b12f/capturing-the-print-screen-key – Surfbutler

Antwort

17

Nun, wenn Sie Probleme mit dem System Haken haben, ist hier fertige Lösung (basierend auf http://www.dreamincode.net/forums/topic/180436-global-hotkeys/):

definiert statische Klasse in Ihrem Projekt:

public static class Constants 
{ 
    //windows message id for hotkey 
    public const int WM_HOTKEY_MSG_ID = 0x0312; 
} 

definiert Klasse im Projekt:

public class KeyHandler 
{ 
    [DllImport("user32.dll")] 
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk); 

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

    private int key; 
    private IntPtr hWnd; 
    private int id; 

    public KeyHandler(Keys key, Form form) 
    { 
     this.key = (int)key; 
     this.hWnd = form.Handle; 
     id = this.GetHashCode(); 
    } 

    public override int GetHashCode() 
    { 
     return key^hWnd.ToInt32(); 
    } 

    public bool Register() 
    { 
     return RegisterHotKey(hWnd, id, 0, key); 
    } 

    public bool Unregiser() 
    { 
     return UnregisterHotKey(hWnd, id); 
    } 
} 

hinzufügen usings:

using System.Windows.Forms; 
using System.Runtime.InteropServices; 

jetzt, fügen Sie in Ihrem Formular Feld:

private KeyHandler ghk; 

und in Formularkonstruktor:

ghk = new KeyHandler(Keys.PrintScreen, this); 
ghk.Register(); 

diese zwei Methoden zum Formular hinzufügen:

private void HandleHotkey() 
{ 
     // Do stuff... 
} 

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == Constants.WM_HOTKEY_MSG_ID) 
     HandleHotkey(); 
    base.WndProc(ref m); 
} 

HandleHotkey ist Ihre Schaltfläche Presseführer. Sie können die Taste ändern, indem Sie verschiedene Parameter hier übergeben: ghk = new KeyHandler(Keys.PrintScreen, this);

Jetzt reagiert Ihr Programm auf Buton-Eingabe, auch wenn nicht fokussiert.

+0

Wie bearbeite ich diesen Code, wenn ich zwei verschiedene Hotkeys mit zwei verschiedenen Funktionen haben wollte? Kann ich irgendwie "WndProc" oder "HandleHotkey" überprüfen, welche Taste gedrückt wurde? – user1696947

+0

Kann dies angepasst werden, um Tastenkombinationen zu handhaben? Wie CTRL-N – MrVimes

0

Die API GetAsyncKeyState() ist möglicherweise eine vollkommen akzeptable Alternative zum Einrichten von Windows Hook.

Dies hängt davon ab, wie Sie die Eingabe erhalten möchten. Wenn Sie ereignisgesteuerte Benachrichtigungen bevorzugen, ist ein Hook der richtige Weg. Wenn Sie jedoch Polling die Tastatur für Statusänderungen bevorzugen, können Sie die API oben verwenden.

Hier ist ein einfaches Beispiel dafür, wie GetAsyncKeyState zu verwenden:
Abgeleitet von Pinvoke.NET

[DllImport("User32.dll")] 
private static extern short GetAsyncKeyState(int vKey); 

private static readonly int VK_SNAPSHOT = 0x2C; //This is the print-screen key. 

//Assume the timer is setup with Interval = 16 (corresponds to ~60FPS). 
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    short keyState = GetAsyncKeyState(VK_SNAPSHOT); 

    //Check if the MSB is set. If so, then the key is pressed. 
    bool prntScrnIsPressed = ((keyState >> 15) & 0x0001) == 0x0001; 

    //Check if the LSB is set. If so, then the key was pressed since 
    //the last call to GetAsyncKeyState 
    bool unprocessedPress = ((keyState >> 0) & 0x0001) == 0x0001; 

    if (prntScrnIspressed) 
    { 
     //TODO Execute client code... 
    } 

    if (unprocessedPress) 
    { 
     //TODO Execute client code... 
    } 
} 
Verwandte Themen