GetAsyncKeyState Systemweite Mausklicks - Dauerklickverhalten

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

    GetAsyncKeyState Systemweite Mausklicks - Dauerklickverhalten

    Hallo Leute,

    folgender Code funktioniert grundsätzlich.
    Jedoch stört mich, dass sich der Beepton beim "Gedrückthalten" der Maustaste immer wiederholt.
    Habt Ihr eine Idee, wie ich das so hinbekomme, dass nur der einzelne Mausklick erfasst wird?

    Die Anwendung soll Touchscreens die keine akkustische Rückmeldung haben mit einem Beepton ausstatten.
    Da soll es bei einem Fingerklick aber auch nur einmal piepsen - egal wie lange man den Finger gedrückt hält.

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.ComponentModel
    3. Imports System.Runtime.InteropServices
    4. Public Class FRM_Hauptform
    5. <DllImport("user32.dll")>
    6. Public Shared Function GetAsyncKeyState(ByVal vKey As Int32) As Short
    7. End Function
    8. Declare Function Beep Lib "kernel32.dll" (ByVal dwFreq As Int32, ByVal dwDuration As Int32) As Int32
    9. Public TonHoehe As Integer
    10. Public TonDauer As Integer
    11. Private Sub FRM_Hauptform_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    12. TonHoehe = My.Settings.Hoehe
    13. TonDauer = My.Settings.Dauer
    14. TrackBar_Hoehe.Value = TonHoehe
    15. TrackBar_Dauer.Value = TonDauer
    16. End Sub
    17. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    18. Timer1.Enabled = False
    19. If GetAsyncKeyState(&H1) <> 0 Then
    20. Beep(TonHoehe, TonDauer) 'Frequenz, Dauer
    21. ElseIf GetAsyncKeyState(&H2) <> 0 Then
    22. Beep(TonHoehe, TonDauer) 'Frequenz, Dauer
    23. End If
    24. Timer1.Enabled = True
    25. End Sub
    26. Private Sub TrackBar_Hoehe_Scroll(sender As Object, e As EventArgs) Handles TrackBar_Hoehe.Scroll
    27. TonHoehe = TrackBar_Hoehe.Value
    28. End Sub
    29. Private Sub TrackBar_Dauer_Scroll(sender As Object, e As EventArgs) Handles TrackBar_Dauer.Scroll
    30. TonDauer = TrackBar_Dauer.Value
    31. End Sub
    32. Private Sub FRM_Hauptform_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    33. My.Settings.Hoehe = TonHoehe
    34. My.Settings.Dauer = TonDauer
    35. My.Settings.Save()
    36. End Sub
    37. Private Sub Button_Exit_Click(sender As Object, e As EventArgs) Handles Button_Exit.Click
    38. Me.Close()
    39. End Sub
    40. Private Sub Button_Minimize_Click(sender As Object, e As EventArgs) Handles Button_Minimize.Click
    41. Me.WindowState = FormWindowState.Minimized
    42. End Sub
    43. End Class
    Bilder
    • 29092021124606.jpg

      45,65 kB, 422×252, 39 mal angesehen
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    VB.NET-Quellcode

    1. Public Shared Function GetAsyncKeyState(ByVal vKey As Int32) As Short
    Zunächst einmal kannst Du diese Prozedur auch direkt mit Keys deklarieren:

    VB.NET-Quellcode

    1. Public Shared Function GetAsyncKeyState(ByVal vKey As Keys) As Short

    Du schaltest den Timer in der Tick-Prozedur aus und gleich wieder an.
    Kopple dies an KeyDown und KeyUp bzw.Mouse~.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich würd's eben so umsetzen:

    VB.NET-Quellcode

    1. Private IgnoreMouseButton1IsDown As Boolean = False
    2. Private IgnoreMouseButton2IsDown As Boolean = False
    3. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    4. If GetAsyncKeyState(&H1) < 0 AndAlso Not IgnoreMouseButton1IsDown Then Beep(TonHoehe, TonDauer) : IgnoreMouseButton1IsDown = True
    5. If GetAsyncKeyState(&H1) = 0 Then IgnoreMouseButton1IsDown = False
    6. If GetAsyncKeyState(&H2) < 0 AndAlso Not IgnoreMouseButton2IsDown Then Beep(TonHoehe, TonDauer) : IgnoreMouseButton2IsDown = True
    7. If GetAsyncKeyState(&H2) = 0 Then IgnoreMouseButton2IsDown = False
    8. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Vielen Dank. Grundsätzlich würde Dein Code funktionieren und das machen was ich möchte.
    Jedoch ist die "Performance" irgendwie "grottig". Bei 10 etwas schnelleren Klicks werden gefühlt 3 Klicks "verschluckt".
    Habe auch schon versucht das GetAsync... nur einmal in eine Variable auszulesen und die rechte Maustaste einmal wegzulassen, wird aber nicht besser. Timer ist auf 100ms eingestellt.
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Hey,

    also das Klicks verschluckt werden, wundert mich nicht, denn je länger dein Ton abgespielt wird um so länger "bleibst du" in dieser Codezeile.

    Probier mal dies:

    VB.NET-Quellcode

    1. Dim start As DateTime = DateTime.Now
    2. Beep(500, 1000)
    3. Dim dura As TimeSpan = DateTime.Now - start
    4. Debug.WriteLine(dura.TotalMilliseconds)


    Du wirst feststellen, das der Ablauf solange blockiert ist wie der Ton wiedergegeben wird. Das bedeutet es kann in diesen Zeitraum garnicht auf klicks reagiert werden. Ich täte einfach eine Bibliothek zum abspielen von Audio nehmen.

    Wenn du aber auf zusätzliche DLLs verzichten willst, kannste auch damit Sound wiedergeben.
    Einfacher MediaPlayer per Media Foundation (IMFMediaEngine(Ex))
    @dive26 Beschreib mal, was genau passieren soll.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank, habs gelöst.
    Der Code von Vaporized hat gepasst. Habe den Timer von 100ms auf 10ms gestellt.

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Timer Tick 10ms
    3. ''' </summary>
    4. ''' <param name="sender"></param>
    5. ''' <param name="e"></param>
    6. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    7. Timer1.Enabled = False
    8. 'linke Maustaste (Touch Finger geklickt)
    9. Status = GetAsyncKeyState(&H1)
    10. If Status < 0 AndAlso Not IgnoreMouseButton1IsDown Then Beep(TonHoehe, TonDauer) : IgnoreMouseButton1IsDown = True
    11. If Status = 0 Then IgnoreMouseButton1IsDown = False
    12. 'rechte Maustaste (Touch Finger gedrückt halten)
    13. Status = GetAsyncKeyState(&H2)
    14. If Status < 0 AndAlso Not IgnoreMouseButton2IsDown Then Beep(TonHoehe - 400, TonDauer + 20) : IgnoreMouseButton2IsDown = True
    15. If Status = 0 Then IgnoreMouseButton2IsDown = False
    16. Timer1.Enabled = True
    17. End Sub

    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „dive26“ ()

    Also im ersten Post steht auch, solange gedrückt gehalten wird. Da ist halt das Problem, das man nie weiss, wie lange ein User den Figer aufmScreen/MouseButton hat, du aber eine Zeit für Beep angeben musst, in dieser Zeit kannste auch nicht auf Klicks reagieren. Da kannste nur mit Threading was verbessern, aber wenn MouseDown bleibt, startet der Ton weiterhin erneut mit einer hörbaren Unterbrechung.

    Das Sinnvollste ist imo eine Bibliothek oder die IMFMediaEngine zu nutzen, machste eine kleine Audiodatei, diese spielst du dann solange ab, wie der User halt klickt. Hat auch einen weiteren Vorteil, du kannst dem User die Möglichkeit geben, eigene Sounds zu nutzen. Oder auch zusätzlich verschiedene von dir kreierte Sounds gegen Aufpreis.
    @Takafusa Vielen Dank. Funktioniert ja jetzt einwandfrei (siehe mein voriger Post).

    Falls das Tool (AudibleTouch) jemand verwenden möchte. Hier ist der kostenlose Download: bonit.at/download.asp
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at