Schnell und einfach einen Hotkey einrichten

    • VB.NET

    Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von FAtheone.

      Schnell und einfach einen Hotkey einrichten

      Oft wurde schon gefragt:

      - Wie Frage ich Tastatureingaben Systemweit ab
      - Wie mache ich einen Hotkey etc.

      Dazu habe ich hier ein einfaches kleines Tutorial:


      Die ganze Sache funktioniert mit einer API.

      Schritt 1:

      Wir Deklarieren die API:

      VB.NET-Quellcode

      1. 'Hier die API Deklaration
      2. Private Declare Function GetAsyncKeyState Lib "User32" (ByVal vKey As Integer) As Short



      Schritt 2:


      Wir brauchen nun noch eine Funktion, welche die GetAsyncKeyState benutzt und den Wert ausliest.
      Entweder man macht eine Funktion für einen einzelnen Hotkey oder für mehrere. Diese Funktion ist
      für mehrere Geignet. So kann einfach ein Aufruf erfolgen mit der Taste die abgefragt wird.

      VB.NET-Quellcode

      1. 'Diese Funktion prüft ob die Taste B im Moment gedrückt ist. Wenn ja dann gibt die Funktion True zurück.
      2. Function GetTaste(ByVal Taste As Integer) As Boolean
      3. 'Hier kann jede Belibige Taste genommen werden. Z.B. Keys.B
      4. If GetAsyncKeyState(Taste) = -32767 Then
      5. Return True
      6. End If
      7. End Function


      Schritt 3:

      Mit Hilfe dieser Methode wird eine bestimmte Taste abgefragt. Gibt die oben geschriebene Funktion ein True
      zurück, so wir der Befehl im If Block ausgeführt. Man könnte natürlich auch mehrere Hotkeys abfragen oder per ByVal übergeben lassen.
      Um diese Funktion die ganze Zeit auszuführen, braucht man eine Schleife.
      An diesem Beispiel verwende ich einen Do/Loop Schleife, welche in einem separaten Thread läuft.

      VB.NET-Quellcode

      1. 'Hier die Deklaration des Threads
      2. Dim hotkeyThread As New Threading.Thread(AddressOf CheckKeyPressed)
      3. 'Das ist die Sub, welche prüft, ob ein Hotkey gedrückt wurde.
      4. Sub CheckKeyPressed()
      5. Do
      6. If GetTaste(Keys.B) = True Then
      7. 'Aktion die beim Drücken des Hotekeys passiert.
      8. MessageBox.Show("Die Taste B wurde gedrückt!")
      9. End If
      10. Loop
      11. End Sub


      Schritt 4:

      Der Thread muss natürlich auch gestartet wird. Dies wird im Load Event gemacht.

      VB.NET-Quellcode

      1. 'Hier wird der Thread gestartet.
      2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      3. hotkeyThread.Start()
      4. End Sub


      Natürlich kann man sich das ganze auch umschreiben, sodass es für mehrere Hotkeys gilt. Doch dies soll hier ja nur ein
      kleines Beispiel sein. Wer meine Methode nicht nutzen möchte, der schaut etwas weiter unten nach der Hook Methode,
      welche auch weniger Ressourcen verbraucht.

      Ich hoffe, dass das alles soweit verständlich erklärt ist. Falls nicht dann schreibt mir das bitte.

      Ansonsten wünsche ich euch viel Spaß damit :thumbup:

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „MB-Tech“ ()

      Man kann auch anstatt einen Timer einen BackgroundWorker oder einen eigenen Thread dafür nehmen. Dabei hängt sich auch nicht die Form (ist oft so) auf.
      Für einen systemweiten Hotkey kann man auch einen Hook nehmen. Dabei wird dann per Event das ganze auswertbar gemacht. Wäre gut wenn man das nicht so of brauch (Screenshot-tool o.Ä.). Die hier beschriebene Weise ist gut für Spiele o.Ä., da klar ist dass Tasten gedrückt werden und diese dementsprechend abgefragt werden müssen (wenn man ein DX-Spiel macht mit XNA muss man nicht die API nehmen, dafür kann man dann aus XNA.FrameWork.Input mit Mouse, Keyboard oder GamePad die Daten auslesen).

      Ich hoffe meine paar Anmerkungen helfen anderen weiter.

      Mangafreak1995 schrieb:

      Für einen systemweiten Hotkey kann man auch einen Hook nehmen.


      Das ist aber alles andere als trivial in VB.
      Für Hooks kenn ich nur die API SetWindowsHookEx.. und damit einen systemweiten Hook einrichten ist mit VB allein unmöglich.
      Falls es eine andere Möglichkeit für nen systemweiten Hook in VB gibt, dann nur raus mit der Info :D

      Gruß Mono
      Das ist meine Signatur und sie wird wunderbar sein!
      Hallo,

      also die Funktion wie sie im ersten Posting steht ist eigentlich nicht brauchbar, außer der Benutzer steht auf laute Lüftergeräusche.
      Denn der Timer führt eine Endlosschleife aus, die die CPU dauerbelastet. Führ diesen Code doch mal aus und schau im Taskmanager auf deine CPU_Auslastung, diese dürfte bei über 50% liegen, für nichts!

      Deswegen kann ich jedem nur davon abraten, diesen Code zu verwenden.

      Hier ist ein Beispiel wie man es richtig macht:

      Beispiel: Mehrfache Hotkeys registrieren wie z.B. Alt+D, Alt+C,
      etc.

      VB.NET-Quellcode

      1. Imports System.Runtime.InteropServices
      2. Public Class Form1
      3. Public Const MOD_ALT As Integer = &H1 '//Alt key
      4. Public Const WM_HOTKEY As Integer = &H312
      5. _
      6. Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, _
      7. ByVal id As Integer, ByVal fsModifiers As Integer, _
      8. ByVal vk As Integer) As Integer
      9. End Function
      10. _
      11. Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
      12. ByVal id As Integer) As Integer
      13. End Function
      14. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      15. RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.D)
      16. RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.C)
      17. End Sub
      18. Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
      19. If m.Msg = WM_HOTKEY Then
      20. Dim id As IntPtr = m.WParam
      21. Select Case (id.ToString)
      22. Case "100"
      23. MessageBox.Show("Sie haben Tastenkombination ALT+D gedrückt")
      24. Case "200"
      25. MessageBox.Show("Sie haben Tastenkombination ALT+C gedrückt")
      26. End Select
      27. End If
      28. MyBase.WndProc(m)
      29. End Sub
      30. Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
      31. UnregisterHotKey(Me.Handle, 100)
      32. UnregisterHotKey(Me.Handle, 200)
      33. End Sub
      34. End Class

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „bigbasti“ ()

      ich selber benutze dafür eine Klasse die auf folgendem Code von Tim Hartwig aufbaut, allerdings wird in seinem Beispiel das Misslingen des RegisterHotkey nicht abgefangen.

      @MB-Tech vielleicht magst Du ja Dein Tutorial etwas anpassen, wie BigBasti schon sagte: eine Timer basierende Lösung ist eher suboptimal ;)
      Wenn ich jetzt mehrere Tasten belegen will, muss ich dann das hier:

      VB.NET-Quellcode

      1. If GetAsyncKeyState(Keys.A) = -32767 Then
      2. Return True
      3. End If

      immer wieder wiederholen?

      Also sagen wir mal, ich will es für die Tasten A und B. Muss ich dann
      "

      VB.NET-Quellcode

      1. If GetAsyncKeyState(Keys.A) = -32767 Then
      2. Return True
      3. End If
      "

      und danach noch einmal

      VB.NET-Quellcode

      1. If GetAsyncKeyState(Keys.B) = -32767 Then
      2. Return True
      3. End If


      Oder wie?