Konfigurierbare Hotkeys ohne Forms

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Konfigurierbare Hotkeys ohne Forms

    Hallo,

    Ich möchte ein Programm schreiben welches die aktuelle Mausposition per Hotkey in einer Liste speichert, per anderem Hotkey alle Positionen in der Liste nacheinander anklickt (Maus springt hin, dann Klick) und per noch weiterem Hotkey die Liste zurücksetzt. Das Programm soll als SystemTray-Anwendung laufen also über Sub Main() in einem Modul, ohne Form.

    Zudem soll der User über ein Konfigurationsfenster welches über das Kontextmenü des Programmlogos im SysTray einstellen können welche Tasten er verwenden möchte um die Funktionen auszuführen. Am idealsten wäre es wie man es von vielen Programmen (bevorzugt Spielen) kennt mit einem Button, der nach dem Klick schaut welche Tastenkombination der User gewählt hat und diese dann so speichert. Als weitere Anforderung sollen Hotkeys mit zwei Modifizierungstasten bspw. Strg + Alt + Beliebige Taste möglich sein.

    Mir ist RegisterHotkey aus user32 bekannt, diese funktioniert meines Wissens nach aber nur mit einer Form und auch nur mit einer Modifizierungstaste.

    Kurz und Knapp: Ich suche einen Weg um auch komplexe Hotkeys ohne Forms zu Nutzen und beliebig wählen zu können



    @ Artentus: Ich schaue mir das mal an. C# lesen kann ich auch wohl.

    @ windowsfan: Na klar könnte ich das machen, das empfinde ich aber als ein wenig unsauber und außerdem interessiert mich wie es ohne geht. Ich bin relativ perfektionistisch ;). Zudem möchte ich das auch für zukünftige Projekte gebrauchen da ich sehr gerne mit Hotkeys arbeite und in jedem Programm von mir, wo es einigermaßen Sinn ergibt sie zu haben, möchte ich sie auch implementieren.
    In der User32 Klasse im Namespace WinAPI bin ich auf folgenden Schnipsel gestoßen den ich nicht so recht in VB zu übersetzen weiß:

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);



    Wie übersetze ich die return Zeile?
    Der Codeconverter sagt das:

    VB.NET-Quellcode

    1. <DllImport("user32.dll", SetLastError := True)> _
    2. Public Shared Function UnhookWindowsHookEx(hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    3. End Function
    Keine Gewähr für Richtigkeit, ich könnte das selber auch nicht per Hand übersetzen und die Signaturen sind alle von PInvoke.net.
    @ Artentus: Danke, habe das jetzt soweit übersetzt. Folgenden Code habe ich nun in VB übersetzt:

    KeyboardHook-Klasse:
    Spoiler anzeigen

    Edit by ErfinderDesRades: Code entfernt



    Und den WinAPI-Namespace mit User32, Kernel32 und co.


    Wie genau benutze ich jetzt den Hooker um nur bei ausgewählten Tasten das KeyDown Event auszulösen?
    Wenn ich den Code richtig verstanden habe dann wird doch nach erzeugen einer KeyboardHook-Instanz jeder Tastenanschlag wahrgenommen und per KeyDown- / KeyUp- Event weitergegeben, oder? Ich möchte so effizient wie möglich mit den Events sein.

    Könnte es eigentlich sein das ein Sicherheitsprogramm den Keyboard-Hook als Keylogger-Funktion wahrnimmt und mein ganzes Programm als schädlich einstuft? Falls es irgendwann mal andere User außer mir gibt die das Programm benutzen sollen die sicher gehen können, dass ich nicht ihre Keys logge ;)


    @ Earan:


    So wie ich das sehe basiert die Klasse aus deinem Link auf dem exakt selben Unterbau. Nur ist diese quasi schon um die Anforderungen erweitert die ich oben in diesem Kommentar stelle :) Ich schaue mir das mal an und versuche das vielleicht auf Artentus-Lösung selbst umzusetzen.

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

    Frag doch einfach e.KeyCode ab, effizienter kann mans glaube ich nicht machen. Über Effizienz brauchst du dir da aber sowieso keine Gedanken zu machen, dieser Hook setzt auf unterster Ebene an und wird somit quasi sofort ausgelöst.
    Ich hab das bei mir auch schon ausprobiert und mein Antivirus hat nicht Alarm geschlagen. Um sicher zu gehen kannst dus natürlich auch mal bei VirusTotal.com hochladen.
    Hallo,

    Ich beschäftige mich nach Urlaub und Berufschule wieder mit meniem Programm. Leider stehe ich gerade auf dem Schlauch und kriege es nicht hin die Keydown-Events abzufragen. Mein Ansatz sieht so aus.




    Module App.vb

    [...]
    Application.Run()

    Dim kbHook as New KeyboardHook()

    [...]

    Public Sub keyDownEventHandler(byval sender as Object, ByVal e as KeyEventArgs)

    If e.KeyCode = Keys.Space Then
    MsgBox("Space")
    End If

    End Sub

    Starte ich das Programm und drücke die Leertaste passiert jedoch nichts. Ergo fange ich das Event wohl nicht ab. Ich dachte an Handles in der obigen Prozedur, wusste aber nicht wo ich den richtigen Event herkriege.
    Geht es Dir weiterhin nur um HotKeys? Wenn ja, dann schau Dir mal folgendes Konstrukt an:

    VB.NET-Quellcode

    1. Public Class WindowClass : Inherits NativeWindow
    2. Protected Overrides Sub WndProc(ByRef m As Message)
    3. MyBase.WndProc(m)
    4. End Sub
    5. End Class


    Erstell Dir eine Klasse, lass diese von NativeWindow erben, instanziere diese Klasse und Du kannst Deine Hotkeys, die Du festgelegt hast, abfragen. Löse dann entsprechend die Events aus, die Du in Deinem Programm verarbeitest.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    ErfinderDesRades - Moderator - Notiz: LowLevel-Keyboard-Hooks werden auf VBP nicht unterstützt, weil damit kannman zu leicht Malware produzieren, als dass man sich hier darüber in aller Öffentlichkeit austauschen sollte

    Aber ich sehe auch garnet, dass ein LowLevel-Hook erforderlich wäre. mit RegisterHotkey kannste doch ebensogut, systemweit auf Usereingaben reagieren, ohne dass daraus ein Input-Spy gebaut werden kann.
    @ SpaceyX: Ja genau. Das Ding wird später auch im Showroom landen, falls es jemand gebrauchen kann. Aber als ClosedSource, da ich den Auflagen von VBP nachkommen möchte und nicht die Script-kiddies mit potenziell bösem Code füttern möchte ;)

    Ich habe die Klasse so erstellt, wie du sagtest. Leider weiß ich nicht genau wie ich jetzt den Bezug von dieser Klasse zum Rest herstellen sollen. Ich finde die Funktionsnamen der DLLs ziemlich kryptisch und intuitiv kann ich kaum richtig vermuten was diese denn so tun ^^


    @ EDR: Alle Varianten mit RegisterHotkey die ich gefunden habe, brauchten eine Form. Ich werde mir auch mal deine Lösung anschauen.
    Ich probiere gerade die RegisterHotkey-Umsetzung von EDR einzubauen. Komischerweise feuert meine Form, mit der ich die Hotkeys registrieren möchte kein KeyDown-Event.

    Hier der Code:

    VB.NET-Quellcode

    1. Private Sub frmHotkeySelection_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    2. _Proposed = e.KeyData
    3. LblHotkey.Text = _Proposed.ToString
    4. End Sub


    Dieser Code wird aber nie erreicht. Egal wie ich auf mein Klavier einschlage (auch nicht wenn das Fenster direkt im Fokus ist, also quasi OnTop) ;).