Gå til innhold

Hvordan få til: Piltast trykkes inn og command1 aktiveres


Anbefalte innlegg

Var ikke helt sikker på hva jeg skulle søke etter på google så prøver her :woot:

 

Når jeg trykker inn piltast ( opp ) så vil jeg at en knapp ( command1 ) skal aktiveres ( slik at man ser den trykkes inn ). Command1 skal utføre en kommando i seg selv, f.eks gi en msgbox.

 

Hvordan skal jeg få til dette ? Er det mulig ? :o

Lenke til kommentar
Videoannonse
Annonse

Ja, det er mulig. Legg til en timer i formen der du har knappen. Sett "Interval" til 1 på timeren.

 

Lim så dette inn i formens kode:

 


Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer



Private Const WM_KEYDOWN = &H100

Private Const WM_KEYUP = &H101

Private Const VK_SPACE = &H20



Private Sub SimulateClick(Command As CommandButton)



With Command

If .Tag <> "" Then Exit Sub

SendMessage .hwnd, WM_KEYDOWN, VK_SPACE, 0&



DoEvents

Sleep 100 ' Endre nummeret til et høyere tall for

' å la knappen bli presset ned lengre



SendMessage .hwnd, WM_KEYUP, VK_SPACE, 0&



.Tag = "1"

End With



End Sub



Private Sub Timer1_Timer()



If GetAsyncKeyState(vbKeyUp) <> 0 Then SimulateClick Command1 Else Command1.Tag = ""



End Sub

 

Lett ikke sant? :lol:

Lenke til kommentar

Takker :-) funket jo fint det der!

 

 

Men knappen blir deaktivert alt ettersom man skriver inn i tidsintervallet.

 

Er det mulig å lage det til slik at når jeg trykker inn piltasten så aktiveres den knappen, og når jeg slipper piltasten så deaktivers piltasten ? ( med en gang ) ?

 

 

mvh

Lenke til kommentar

Det gjør det faktisk enda enklere. Fjern SimulateClick sub-en og

erstatt timer sub-en med dette:

 


Private Sub Timer1_Timer()



With Command1



If GetAsyncKeyState(vbKeyUp) <> 0 Then

SendMessage .hwnd, WM_KEYDOWN, VK_SPACE, 0&

.Tag = "1"

Else

   If .Tag <> "" Then

   SendMessage .hwnd, WM_KEYUP, VK_SPACE, 0&

   .Tag = ""

   End If

   End If



End With



End Sub

 

Da skulle det virke perfekt.

Lenke til kommentar

Du har vel merket at KeyPress ike gir tilbake vbKeyUp, vbKeyDown o.s.v? vel det gjør KeyDown og KeyUp

Kan du ikke da heller


Private Sub Form1_KeyDown(key As Integer)

 If button = vbKeyUp Then SendMessage Command1.hwnd, WM_KEYDOWN, VK_SPACE, 0&

End Sub

En ting: Ikke bruk timere som sitter på interval 1, det virker litt overflødig.

 

Lag heller en egen thread(avansert) eller en egen sub som kjører en loop.

Start heller en metode i Sub main som kjører en loop(med en DoEvents selvsagt).

 

Du lager threads med å skrive CreateThread(AddressOf MetodeNavn)

Går utifra at CreateThread står i API Viewer

Må sjekke dette nærmere når jeg kommer hjem.

Lenke til kommentar

Problemet med å bruke Form1_KeyDown eller lignende er at av og til er fokusen på et annet objekt. Da blir ikke den eventen startet og koden virker ikke. Jeg valgte å bruke en timer fordi det er den letteste løsningen, men selvsakt kan man også bruke en DO-loop med DoEvents.

 

CreateThread vil neppe hjelpe deg for å bruke lavere systemressurser, men såkalt SubClassing vil (det var sikkert det du mente, GeirGrusom). Her kan du få VB eller programmet ditt til å krasje, men skal du virkelig spare på ressursene er nok dette veien å gå.

 

For å bruke SubClassing se nærmere på SetWindowLong i API-viewer. Men jeg tror ikke det er strevet verd å bruke SubClassing så lenge det ikke er nødvendig. Timere eller DO-looper holder lenge.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...