Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0304: Globaler Hotkey

 von 

Hinweis zum Tippvorschlag  

Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.

Über den Tipp  

Dieser Tippvorschlag ist noch unbewertet.

Der Vorschlag ist in den folgenden Kategorien zu finden:

  • System

Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Hotkey, Keyhook, global

Der Vorschlag wurde erstellt am: 22.08.2008 08:36.
Die letzte Aktualisierung erfolgte am 06.09.2008 12:33.

Zurück zur Übersicht

Beschreibung  

Eigentlich soll damit  Tippvorschlag 2 ersetzt werden, da ich finde meine/diese Variante ist viel besser.

Diese Klasse in diesem Tipp basiert auf einer von Tim Hartwig. siehe hier

Ich habe einige grundlegende Anpassungen vorgenommen, welche die Komplexität um einiges reduzieren.
Ein Frontend habe ich erstellt um die Möglichkeiten zu demonstrieren.

2 Schaltflächen, die eine registriert die Tastenkombination Strg+R und die andere löscht diesen Hotkey wieder.
Für jeden registrierten Hotkey wird ein Event mit der jeweiligen ID ausgelöst.
Alles funktioniert über eine 2 API's (deklariert in der Klasse)

Keine Timer nötig!
Funktioniert systemweit!

Schwierigkeitsgrad

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [15,11 KB]

' Dieser Source stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!
'
' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird.
' In den Zip-Dateien ist er jedoch zu finden.

' --------- Anfang Projektgruppe Globaler Hotkey.sln ---------
' -------- Anfang Projektdatei Globaler Hotkey.vbproj --------
' ---------------- Anfang Datei clsHotkeys.vb ----------------
''' <summary>
''' Mit dieser Klasse kann man sehr leicht eine globale Hotkey funktionalität in seinem Programm einbinden.
''' Man muss nur diese Klasse mit WithEvents deklarieren und ihr eine Form zuweisen die gesubclassed werden soll.
''' Dann muss man nur noch ein paar eigene HotKey-Kombinationen registrieren (z.B. Strg+Alt+X) und diese
''' mit dem Event abfragen bzw, abfangen. Dazu muss man eine eigene HotKeyID angeben um einen bestimmte HotKey
''' Kombination später zu identifizieren wenn diese gedrückt wird. Wenn man z.B. eine Kombination registriert
''' und ihr z.B. die HotKeyID "TEST1" zugewiesen wird, dann kann man später im Event nach dieser ID "TEST1" fragen
''' und dann eine Funktion aufrufen die für diesen HotKey bestimmt wurde.
''' </summary>
''' 
''' <remarks>
''' Ursprung: Tim Hartwig
''' Bearbeitung: Thomas Kriechbaumer
''' </remarks>
Public Class clsHotkeys

    Inherits System.Windows.Forms.NativeWindow
    Implements IDisposable

    Private Declare Function RegisterHotKey Lib "user32" ( _
                             ByVal Hwnd As IntPtr, _
                             ByVal ID As Integer, _
                             ByVal Modifiers As Integer, _
                             ByVal Key As Integer) As Integer

    Private Declare Function UnregisterHotKey Lib "user32" ( _
                             ByVal Hwnd As IntPtr, _
                             ByVal ID As Integer) As Integer

    Public Class HotKeyObject

        Private mHotKey As Keys
        Private mModifier As MODKEY
        Private mHotKeyID As String

        Public Property HotKey() As Keys
            Get
                Return mHotKey

            End Get

            Set(ByVal value As Keys)
                mHotKey = value

            End Set

        End Property

        ''' <summary>
        ''' Modifier-Keys, also Strg, Alt, Win und Shift
        ''' </summary>
        ''' <remarks>Können mit OR verknüpft werden</remarks>
        Public Property Modifier() As MODKEY
            Get
                Return mModifier

            End Get

            Set(ByVal value As MODKEY)
                mModifier = value

            End Set

        End Property

        Public Property HotKeyID() As String
            Get
                Return mHotKeyID

            End Get

            Set(ByVal value As String)
                mHotKeyID = value

            End Set

        End Property

        Sub New(ByVal NewHotKey As Keys, ByVal NewModifier As MODKEY, ByVal NewHotKeyID As String)

            mHotKey = NewHotKey
            mModifier = NewModifier
            mHotKeyID = NewHotKeyID

        End Sub

    End Class

    Private Const WM_HOTKEY As Integer = &H312
    Private mHotKeyList As New System.Collections.Generic.List(Of HotKeyObject)

    ''' <summary>
    ''' Diesem Event wird immer die zugewiesene HotKeyID übergeben wenn eine HotKey Kombination gedrückt wurde.
    ''' </summary>
    Public Event HotKeyPressed(ByVal HotKeyID As String)

    Public Enum MODKEY As Integer
        MOD_ALT = 1
        MOD_CONTROL = 2
        MOD_SHIFT = 4
        MOD_WIN = 8
    End Enum

    Sub New()

        ' Wir machen uns unser eigenes Handle.
        Me.CreateHandle(New CreateParams)

    End Sub

    Protected Overrides Sub Finalize()

        ' Das selbst erstellte Handle zerstören.
        Me.DestroyHandle()
        MyBase.Finalize()

    End Sub

    ''' <summary>
    ''' Diese Funktion fügt einen Hotkey hinzu und registriert ihn auch sofort (wenn möglich)
    ''' </summary>
    ''' <param name="new_KeyCode">Den KeyCode für die Taste</param>
    ''' <param name="new_Modifiers">Die Zusatztasten wie z.B. Strg oder Alt, diese können auch mit OR kombiniert werden</param>
    ''' <returns>true wenn der Hotkey erfolgreich registriert wurde, gab es einen Fehler wird false zurückgegeben</returns>
    ''' <param name="new_HotKeyID">Die ID die der Hotkey bekommen soll um diesen zu identifizieren</param>
    Public Function TryAddHotKey(ByVal new_KeyCode As Keys, ByVal new_Modifiers As MODKEY, _
        ByVal new_HotKeyID As String) As Boolean

        For Each hk As HotKeyObject In mHotKeyList

            ' es könnte ja sein, dass die Tastenkombination schon registriert ist, aber
            ' unter einem anderen Namen
            ' oder der Name wurde schon registriert...
            If hk.HotKey = new_KeyCode And hk.Modifier = new_Modifiers Then Return False
            If hk.HotKeyID = new_HotKeyID Then Return False
        Next

        Dim new_ID As Integer = mHotKeyList.Count
        Dim res As Integer

        res = RegisterHotKey(Me.Handle, new_ID, new_Modifiers, new_KeyCode)

        If res <> 0 Then
            mHotKeyList.Add(New HotKeyObject(new_KeyCode, new_Modifiers, new_HotKeyID))
            Return True

        Else

            Return False
        End If

    End Function

    ''' <summary>
    ''' Diese Funktion entfernt einen Hotkey und deregistriert ihn auch sofort
    ''' </summary>
    ''' <param name="HotKeyID">Gibt die HotkeyID an welche entfernt werden soll</param>
    Public Sub RemoveHotKey(ByVal HotKeyID As String)

        Dim index_to_delete As Integer

        If mHotKeyList.Count = 0 Then Exit Sub

        For Each tmp_HotKey As HotKeyObject In mHotKeyList

            If tmp_HotKey.HotKeyID = HotKeyID Then
                index_to_delete = mHotKeyList.IndexOf(tmp_HotKey)

                Exit For

            End If

        Next

        Dim res As Integer

        UnregisterHotKey(Me.Handle, index_to_delete)

        If res <> 0 Then
            mHotKeyList.RemoveAt(index_to_delete)

        Else

            ' Der Hotkey konnte nicht deregistriert werden, er verbleibt weiterhin im System
            ' (falls er nicht bereits gelöscht wurde)!
        End If

    End Sub

    Protected Overrides Sub WndProc(ByRef m As Message)

        If m.Msg = WM_HOTKEY Then
            RaiseEvent HotKeyPressed(mHotKeyList(CShort(m.WParam)).HotKeyID)
        End If

        MyBase.WndProc(m)

    End Sub

    Private Sub Dispose() Implements IDisposable.Dispose

        Dim res As Integer

        For index_to_delete As Integer = 0 To mHotKeyList.Count - 1
            res = UnregisterHotKey(Me.Handle, index_to_delete)

            ' If res = 0 Then
            ' Der Hotkey konnte nicht deregistriert werden, er verbleibt weiterhin im System
            ' (falls noch vorhanden)!
            ' End If
        Next

    End Sub

End Class

' ----------------- Ende Datei clsHotkeys.vb -----------------
' ----------------- Anfang Datei frmMain.vb  -----------------
''' <summary>
''' Eine kleine GUI um die Möglichkeiten dieser Klasse zu demonstrieren.
''' </summary>
''' <remarks>Thomas Kriechbaumer</remarks>
Public Class frmMain

    Dim mHotkeyEnable As Boolean
    Dim WithEvents Hotkeys As clsHotkeys

    Private Const hk_StrgR As String = "StrgR"
    Private Const hk_WinR As String = "WinR"
    Private Const hk_ShiftQ As String = "ShiftQ"

    ''' <summary>
    ''' Setzt die Hotkeys, erstellt diese, oder löscht sie.
    ''' </summary>
    Public Property HotkeyEnable() As Boolean
        Get
            Return mHotkeyEnable

        End Get

        Set(ByVal value As Boolean)

            If Hotkeys Is Nothing Then Hotkeys = New clsHotkeys()

            If value Then

                Dim res As Boolean

                res = Hotkeys.TryAddHotKey(Keys.R, clsHotkeys.MODKEY.MOD_CONTROL, hk_StrgR)

                If Not res Then
                    MessageBox.Show("Hotkey " & hk_StrgR & " konnte nicht erstellt werden!")
                    Label1.Text = "Registrierung fehlgeschlagen: Strg + R"

                Else

                    Label1.Text = "Strg + R  erfolgreich registriert"
                End If

                res = Hotkeys.TryAddHotKey(Keys.R, clsHotkeys.MODKEY.MOD_WIN, hk_WinR)

                If Not res Then
                    MessageBox.Show("Hotkey " & hk_WinR & " konnte nicht erstellt werden!")
                    Label2.Text = "Registrierung fehlgeschlagen: Win + R"

                Else

                    Label2.Text = "Win + R  erfolgreich registriert"
                End If

                res = Hotkeys.TryAddHotKey(Keys.Q, clsHotkeys.MODKEY.MOD_SHIFT, hk_ShiftQ)

                If Not res Then
                    MessageBox.Show("Hotkey " & hk_ShiftQ & " konnte nicht erstellt werden!")
                    Label3.Text = "Registrierung fehlgeschlagen: Shift + Q"

                Else

                    Label3.Text = "Shift + Q  erfolgreich registriert"
                End If

            Else

                If Hotkeys IsNot Nothing Then
                    Hotkeys.RemoveHotKey(hk_StrgR)
                    Hotkeys.RemoveHotKey(hk_WinR)
                    Hotkeys.RemoveHotKey(hk_ShiftQ)
                End If
            End If

            mHotkeyEnable = value
            Me.Text = "Hotkeys aktiv: " & value

        End Set

    End Property

    ''' <summary>
    ''' wird ausgelöst, wenn ein Hotkey gedrück wurde
    ''' </summary>
    Private Sub Hotkeys_HotKeyPressed(ByVal HotKeyID As String) Handles Hotkeys.HotKeyPressed

        Select HotKeyID

        Case hk_StrgR
            MessageBox.Show("Dein Hotkey wurde ausgelöst! " & hk_StrgR)

        Case hk_WinR
            MessageBox.Show("Dein Hotkey wurde ausgelöst! " & hk_WinR)

        Case hk_ShiftQ
            MessageBox.Show("Dein Hotkey wurde ausgelöst! " & hk_ShiftQ)

    End Select

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _
    Button1.Click

    HotkeyEnable = True

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _
    Button2.Click

    HotkeyEnable = False

End Sub

Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

    HotkeyEnable = False

End Sub

End Class

' ------------------ Ende Datei frmMain.vb  ------------------
' --------- Ende Projektdatei Globaler Hotkey.vbproj ---------
' ---------- Ende Projektgruppe Globaler Hotkey.sln ----------

	

Diskussion  

Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Folgende Diskussionen existieren bereits

Globaler Hotkey - Kriechi 22.08.2008 08:42

Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.