PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hotkeys ?



DoS
18.09.2009, 14:08
Hallo,

ich wollte mal fragen, wie man (in C# kann als Beispiel auch in VB.NET sein, wenn es nicht anders geht) Hotkeys in ein Programm einbaut.

Bisher habe ich das so versucht: http://www.codeproject.com/KB/cs/globalhook.aspx

Allerdings funktioniert das nicht, wenn das Programm nicht maximiert ist oder, wenn ich im Spiel bin.

Ich hätte gerne eine Möglichkeit, die einen Tastendruck von überall annimmt.

Sonst wäre es auch kein sinnvoller Hotkey.


Freue mich auf eure Antwort.

Gruß DoS

Sawyer
18.09.2009, 14:25
Dafür gibt es die API GetAsyncKeySate , mit welcher man die getätigten Tasten Global abfragen kann.

Benötigter Namensraum:

using System.Runtime.InteropServices;Benötigte API:

[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Keys vKey); Code:

while (true)
{
if ((GetAsyncKeyState(Keys.Escape) == -32767)) {
MessageBox.Show("ESC-Taste wurde betätigt!");
}
}Du solltest das ganze (Wenn du es in einer WinForms Anwendung Verwendest) in einem Extra Thread auslagern , da sonst deine Anwendung "Einfriert".

MfG

blackberry
18.09.2009, 14:35
Dazu gibt es noch zu sagen, dass diese Methode die CPU wahrscheinlich auf 100% Belastung hochtreiben wird.
Wichtig ist es einen Sleep-Aufruf einzubauen.

Ansonsten wäre eine bessere Möglichkeit die Verwendung folgender WinAPI-Funktion:
http://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29.aspx

inout
18.09.2009, 14:57
Wenn es unbedingt GetAsyncKeyState() sein soll, sollte man ergänzend evtl. noch sagen, dass hier noch ein 2. Thread + MsgWaitForMultipleObjects() bzw. einem einfachen Event oder meinetwegen auch eine gloable/statische Variable sinnvoll wäre, um das Polling zu vermeiden.

Aber die von BlackBerry genannte Methode mit RegisterHotKey() ist hier wohl die beste Lösung.

DoS
18.09.2009, 17:03
using System.Runtime.InteropServices;Benötigte API:

[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(Keys vKey); Code:

while (true)
{
if ((GetAsyncKeyState(Keys.Escape) == -32767)) {
MessageBox.Show("ESC-Taste wurde betätigt!");
}
}Du solltest das ganze (Wenn du es in einer WinForms Anwendung Verwendest) in einem Extra Thread auslagern , da sonst deine Anwendung "Einfriert".


Also, ich werde erstmal diese Möglichkeit hier nutzen, da sie mir im Moment erstmal am Einfachsten erscheint ( wenn ich in den Ferien mehr Zeit habe, werde ich das noch mal optimieren und mich den anderen Varianten zuwenden).

Also ich habe jetzt das hier oben hinzugefügt:


using System.Runtime.InteropServices;
using System.Threading;Zudem habe ich nun noch folgendes geändert:



public Form1()
{



InitializeComponent();
update(); // update funktion

KeyPress += new KeyPressEventHandler(keypressed); //brauche ich für die ursprüngliche Hotkey Variante, die leider nicht funktionierte, wie sie sollte
while (true)
{
Thread.Sleep(50);
if ((GetAsyncKeyState(Keys.Escape) == -32767))
{
MessageBox.Show("ESC-Taste wurde betätigt!");
}
}Problem: Wenn ich das Programm starte läuft zwar die Updatefunktion (merke ich daran, dass Zone Alarm bei dem Programm nach der Internetverbindung fragt), aber danach kommt nichts mehr (auch komischerweise das Fenster nicht (Form)).

Vermutlich liegt das daran/ am falschen Einbau der "while-Schleife" : "Du solltest das ganze (Wenn du es in einer WinForms Anwendung Verwendest) in einem Extra Thread auslagern , da sonst deine Anwendung "Einfriert"."

Es wäre sehr freundlich, wenn du mir das noch etwas eingehender erklären könntest.

Danke

MfG. -DoS

Sawyer
19.09.2009, 00:13
Ist eigentlich ganz leicht , das beste ist du lagerst die Abfrage für die Keys in eine externe Funktion:

Funktion:

private void KeyAbfragen()
{
while (true)
{
Thread.Sleep(50);
if ((GetAsyncKeyState(Keys.Escape) == -32767))
{
MessageBox.Show("ESC-Taste wurde betätigt!");
}
}
}Danach kannst du aus der main Funktion heraus , diese Funktion in einem neuem Thread starten , wodurch die Anwendung problemlos laufen sollte , ohne einzufrieren.

Aufruf:

private void Form1_Load(object sender, EventArgs e)
{
Thread th = new Thread(KeyAbfragen);
th.Start();
}MfG , Sawyer