Avatar billede blueice Nybegynder
18. maj 2007 - 13:47 Der er 14 kommentarer

Keystroke record

Hej jeg sidder og er ved at lave en macro til et spil (en bot)
den er godt nok ikke lavet i VB, men jeg mangler et program til at optage mine keystrokes

Ved det skal gøres med global hooks, eller noget i den stil, men jeg kan ikke hitte ud af det. Det andet problem jeg har er at den skal optage tiden til keystroke relativ efter det andet altså

Fx a trykkes først 5 sek senere trykkes b derefter trykkes c 2 sek senere

a=0
b=5
c=2

Hvordan får man den til det?
Avatar billede blueice Nybegynder
18. maj 2007 - 13:50 #1
Vil meget gerne se noget kode da jeg ikke er en så stor haj i VB :)
Giver gerne flere points
Avatar billede h7iws Nybegynder
22. maj 2007 - 19:54 #2
Hmm, det burde ikke være noget problem, med AutoItX kunne det nemt laves ...
prøv at søge efter autoitx 3 og hent den, så laver jeg lige et kode eksempel til dig ...
Avatar billede blueice Nybegynder
14. juli 2007 - 18:32 #3
Så er den downloadet :
Hvordan får man den til at vente, og er det mulig at recorde det man laver fx også med museklik?
Avatar billede h7iws Nybegynder
15. juli 2007 - 04:01 #4
vha. noget kode Sjh herinde har lavet:
http://vbhansen.dk/spm/505035/vbKeyboard.zip
http://vbhansen.dk/spm/538986/MouseHookPos.zip
Kan du optage keys+mouse events, herefter afspille dem vha. AutoItX.

Flg. kode er baseret på Sjh's kode,
den består af modulerne frmMain (redigeret), modKeyboard.bas (ej redigeret) og modMouseHook.bas (redigeret).

Lav 3 commandButtons command1, command2 og cammand3
indsæt flg. kode i frmMain.frm

**** frmMain.frm code ****

Option Explicit

Dim KeysLogged As String
Dim MouseX As Integer
Dim MouseY As Integer

Public Sub HookKeyDown(KeyCode As Integer, Shift As Integer)

  Select Case Shift
        Case 1 'SHIFT
            KeysLogged = KeysLogged & "event-key+" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "shift+" & KeyGen(KeyCode)
        Case 2 'CTRL
            KeysLogged = KeysLogged & "event-key^" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "ctrl+" & KeyGen(KeyCode)
        Case 3 'SHIFT + CTRL
            KeysLogged = KeysLogged & "event-key^+" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "ctrl+shift+" & KeyGen(KeyCode)
        Case 4 'ALT
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "alt+" & KeyGen(KeyCode)
        Case 5 'ALT + SHIFT
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "alt+shift+" & KeyGen(KeyCode)
        Case 6 'ALT + CTRL
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "ctrl+alt+" & KeyGen(KeyCode)
        Case 7 'ALT + SHIFT + CTRL
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & "ctrl+alt+shift+" & KeyGen(KeyCode)
        Case Else
            KeysLogged = KeysLogged & "event-key+" & KeyGen(KeyCode)
            lstKey.AddItem "Keyboard: " & KeyGen(KeyCode)
  End Select
End Sub

Private Sub Command1_Click()
  lstKey.Clear
  Call HookKeyboard(Me) '** starter optagelsen
  Call SetMouseHook(Me)
  KeysLogged = ""
End Sub

Private Sub Command2_Click()
    Call UnHookKeyboard '** slukker for optagelsen
    Call UnMouseHook
    '** afspiller 'macroen' (AutoItX)
    Dim w, i
    Dim oAutoIt
   
    Set oAutoIt = CreateObject("AutoItX3.Control")
   
    MsgBox "tryk når du er klar"
   
    w = Split(KeysLogged, "event-")
    For i = 0 To UBound(w)
        Debug.Print "'" & w(i) & "'"
        Select Case Left(w(i), 3)
            Case "mus":
                oAutoIt.MouseClick GetMouseEventInfo(w(i), 3), GetMouseEventInfo(w(i), 1), GetMouseEventInfo(w(i), 2)
            Case "key":
                oAutoIt.Send Right(w(i), Len(w(i)) - 3)
            Case Else: MsgBox "'" & w(i) & "' er en fejl!", vbCritical, "Fejl"
        End Select
    Next
   
    MsgBox "slut!"
   
End Sub

Function GetMouseEventInfo(saved_data, nr As Integer)
    Dim e
    e = Split(saved_data, ":")
    GetMouseEventInfo = e(nr)
End Function

Private Sub Command3_Click()
    KeysLogged = "" '** starter på ny optagelse
    Call HookKeyboard(Me) '** starter optagelsen
    Call SetMouseHook(Me)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Call UnHookKeyboard '** slukker for optagelsen
    Call UnMouseHook
End Sub

Public Sub API_MouseMove(X As Long, Y As Long)
    MouseX = X
    MouseY = Y
End Sub

Public Sub API_MouseEvent(button As String)
    KeysLogged = KeysLogged & "event-mus:" & MouseX & ":" & MouseY & ":" & button
    lstKey.AddItem "Mouse:    " & "X:" & MouseX & " Y:" & MouseY & " " & button
End Sub

Function KeyGen(KeyAsciiCode As Integer)
    Dim q As String
    q = Chr(KeyAsciiCode)
    If q = "!" _
    Or q = "#" _
    Or q = "+" _
    Or q = "^" _
    Or q = "{" _
    Or q = "}" _
    Or q = " " _
    Or q = vbCrLf _
    Or q = vbCr _
    Or q = vbLf Then
        q = "{" & q & "}"
    End If
    KeyGen = q
    '** denne funktion forhindre misforståelserne der opstår ved
    '** at tegnene som ! ^ + osv. har betydninger som alt, control og shift, når de bruges med AutoItX
End Function

**** frmMain.frm code end ****


**** ModKeyboard.frm code ****

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
                        Destination As Any, _
                        Source As Any, _
                        ByVal Length As Long)

Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
                        ByVal idHook As Long, _
                        ByVal lpfn As Long, _
                        ByVal hmod As Long, _
                        ByVal dwThreadId As Long) As Long

Private Declare Function CallNextHookEx Lib "user32" ( _
                        ByVal hHook As Long, _
                        ByVal nCode As Long, _
                        ByVal wParam As Long, _
                        lParam As Any) As Long

Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
                        ByVal hHook As Long) As Long

Private Declare Function GetKeyState Lib "user32" ( _
                        ByVal nVirtKey As Long) As Integer

Private Const HC_ACTION      As Long = 0
Private Const WH_KEYBOARD_LL As Long = 13

Private Type KBDLLHOOKSTRUCT
        vkCode As Long
        scanCode As Long
        Flags As Long
        Time As Long
        dwExtraInfo As Long
End Type

Private objForm As Form
Private hkKeyboard As Long
Private KHS As KBDLLHOOKSTRUCT

Private Function KeyboardProc(ByVal nCode As Long, _
                              ByVal wParam As Long, _
                              ByVal lParam As Long) As Long
  If nCode = HC_ACTION Then
    Call CopyMemory(KHS, ByVal lParam, Len(KHS))
    With KHS
        Select Case .Flags
              Case 0, 1, 32, 33, 128
                Dim mShift As Integer
                If (GetKeyState(vbKeyShift) And &HF0000000) Then
                  mShift = 1            'Shift
                End If

                If (GetKeyState(vbKeyControl) And &HF0000000) Then
                  mShift = (mShift + 2) 'Ctrl
                End If

                If (GetKeyState(vbKeyMenu) And &HF0000000) Then
                  mShift = (mShift + 4) 'Alt og AltGr
                End If
               
                'De 128 bruges af Alt og AltGr. og skal derfor ikke give en tast, _
                ellers ville den taste 2 gange.
                If .Flags <> 128 Then
                  Call objForm.HookKeyDown(CInt(.vkCode), mShift)
                End If
        End Select
    End With
  End If
  KeyboardProc = CallNextHookEx(ByVal 0, _
                                ByVal nCode, _
                                ByVal wParam, _
                                ByVal lParam)
End Function

Public Sub HookKeyboard(frm As Form)
  Set objForm = frm
  Call UnHookKeyboard
  hkKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, _
                                AddressOf KeyboardProc, _
                                App.hInstance, 0)
End Sub

Public Sub UnHookKeyboard()
  If hkKeyboard <> 0 Then
    Call UnhookWindowsHookEx(hkKeyboard)
    hkKeyboard = 0
  End If
End Sub

**** ModKeyboard.Bas code end ****

**** ModMouseHook.Bas code ****

Option Explicit

Private Type POINTAPI
        X As Long
        Y As Long
End Type

Private Type MSLLHOOKSTRUCT
        pt          As POINTAPI
        MouseData  As Long
        Flags      As Long
        Time        As Long
        dwExtraInfo As Long
End Type

Private Declare Function SetWindowsHookEx Lib "user32" _
                        Alias "SetWindowsHookExA" _
                        (ByVal idHook As Long, _
                        ByVal lpfn As Long, _
                        ByVal hmod As Long, _
                        ByVal dwThreadId As Long) As Long
 
Private Declare Function UnhookWindowsHookEx Lib "user32" _
                        (ByVal hHook As Long) As Long

Private Declare Function CallNextHookEx Lib "user32" _
                        (ByVal hHook As Long, _
                        ByVal nCode As Long, _
                        ByVal wParam As Long, _
                        ByVal lParam As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" _
                        Alias "RtlMoveMemory" _
                        (pDest As Any, _
                        pSource As Any, _
                        ByVal cbLength As Long)

' Left mouse button
Private Const WM_LBUTTONDBLCLK As Long = &H203
Private Const WM_LBUTTONUP    As Long = &H202
Private Const WM_LBUTTONDOWN  As Long = &H201

' Midt mouse button
Private Const WM_MBUTTONDBLCLK As Long = &H209
Private Const WM_MBUTTONDOWN  As Long = &H207
Private Const WM_MBUTTONUP    As Long = &H208

' Right mouse button
Private Const WM_RBUTTONDBLCLK As Long = &H206
Private Const WM_RBUTTONDOWN  As Long = &H204
Private Const WM_RBUTTONUP    As Long = &H205

Private Const WM_MOUSEMOVE  As Long = &H200
Private Const WH_MOUSE_LL    As Long = 14&
Private Const HC_ACTION      As Long = 0&

Private m_objForm As Object
Private m_hLLMouseHook As Long

Private Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If nCode = HC_ACTION Then
    Select Case wParam
          Case WM_MOUSEMOVE
            Dim MHook As MSLLHOOKSTRUCT
            Call CopyMemory(MHook, ByVal lParam, Len(MHook))
            Call m_objForm.API_MouseMove(MHook.pt.X, MHook.pt.Y)
          Case WM_LBUTTONUP
            Call m_objForm.API_MouseEvent("left")
          Case WM_MBUTTONUP
            Call m_objForm.API_MouseEvent("middle")
          Case WM_RBUTTONUP
            Call m_objForm.API_MouseEvent("right")
          Case Else
            '** Call m_objForm.API_MouseEvent("???" & wParam) to look-up new mouse events (ie. 4th button etc. ?? )
    End Select
End If

LowLevelMouseProc = CallNextHookEx(m_hLLMouseHook, nCode, wParam, lParam)
End Function


Public Sub SetMouseHook(objForm As Object)
  If m_hLLMouseHook = 0 Then
    m_hLLMouseHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf LowLevelMouseProc, App.hInstance, 0&)
    Set m_objForm = objForm
  End If
End Sub

Public Sub UnMouseHook()
  If m_hLLMouseHook <> 0 Then
    Call UnhookWindowsHookEx(m_hLLMouseHook)
    m_hLLMouseHook = 0
  End If
End Sub

**** ModMouseHook.bas code end ****

Jeg vil ikke have point for noget en anden har lavet, jeg har blot redigeret en lille smule, og det jeg har lavet, er kun af dårlig kvalitet.
Avatar billede blueice Nybegynder
25. juli 2007 - 17:38 #5
Optager denne også hvorlang tid der er i mellem de forskellige key strokes? syntes ikke jeg har kunnet se en timer nogle steder, eller er det bare mig der har overset noget?
Avatar billede h7iws Nybegynder
28. juli 2007 - 04:45 #6
Nej, det gør den ikke, men kan godt lave den ændring, kræver bare noget tid, hvis det er ok, så skal jeg nok se på det !

vh Emil
Avatar billede blueice Nybegynder
28. juli 2007 - 17:30 #7
Det er helt ok,
Det er nemlig vigtig med tiden, da jeg skal trykke bestemte taster i en given rækkefølge efter en given tid
Avatar billede h7iws Nybegynder
08. august 2007 - 06:52 #8
Er på det stadigvæk, men der er lige opstået nogle problemer på hjemmebanen, så er nok først tilbage om noget tid (5dage ca.)

Håber det er ok, men ellers er der ved at være hul igennem ;)
Avatar billede blueice Nybegynder
14. august 2007 - 16:51 #9
Det lyder super, altså at der er ved at være hul igennem
Avatar billede h7iws Nybegynder
14. august 2007 - 23:05 #10
'** har kun ændret i frmMain, og den ser nu således ud **

Option Explicit

Dim KeysLogged As String
Dim MouseX As Integer
Dim MouseY As Integer
Dim StartTime As Long

Private Declare Function GetTickCount Lib "kernel32" () As Long        '** tid
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) '** sov

Public Sub HookKeyDown(KeyCode As Integer, Shift As Integer)
  Dim nu As String
  nu = "##" & (GetTickCount - StartTime)
 
  Select Case Shift
        Case 1 'SHIFT
            KeysLogged = KeysLogged & "event-key+" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "shift+" & KeyGen(KeyCode)
        Case 2 'CTRL
            KeysLogged = KeysLogged & "event-key^" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "ctrl+" & KeyGen(KeyCode)
        Case 3 'SHIFT + CTRL
            KeysLogged = KeysLogged & "event-key^+" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "ctrl+shift+" & KeyGen(KeyCode)
        Case 4 'ALT
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "alt+" & KeyGen(KeyCode)
        Case 5 'ALT + SHIFT
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "alt+shift+" & KeyGen(KeyCode)
        Case 6 'ALT + CTRL
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "ctrl+alt+" & KeyGen(KeyCode)
        Case 7 'ALT + SHIFT + CTRL
            KeysLogged = KeysLogged & "event-key!" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & "ctrl+alt+shift+" & KeyGen(KeyCode)
        Case Else
            KeysLogged = KeysLogged & "event-key+" & KeyGen(KeyCode) & nu
            lstKey.AddItem "Keyboard: " & KeyGen(KeyCode)
  End Select
 
  StartTime = GetTickCount()
End Sub

Private Sub Command1_Click()
  lstKey.Clear
  Call HookKeyboard(Me) '** starter optagelsen
  Call SetMouseHook(Me)
  KeysLogged = ""
End Sub

Private Sub Command2_Click()
    Call UnHookKeyboard '** slukker for optagelsen
    Call UnMouseHook
    '** afspiller 'macroen' (AutoItX)
    Dim w, i
    Dim oAutoIt
   
    Set oAutoIt = CreateObject("AutoItX3.Control")
    Dim svar
    svar = MsgBox("Vil du afspille macro?", vbOKCancel, "Macro-dims!")
   
    If svar = vbOK Then
        w = Split(KeysLogged, "event-")
        Debug.Print KeysLogged
        For i = 1 To UBound(w)
            '** Debug.Print "'" & w(i) & "'"
            Call Sleep(event_handle(w(i), 1))
            Select Case Left(w(i), 3)
                Case "mus":
                    oAutoIt.MouseClick GetMouseEventInfo(event_handle(w(i), 0), 3), GetMouseEventInfo(event_handle(w(i), 0), 1), GetMouseEventInfo(event_handle(w(i), 0), 2)
                Case "key":
                    oAutoIt.Send Right(event_handle(w(i), 0), Len(event_handle(w(i), 0)) - 3)
                Case Else: MsgBox "'" & w(i) & "' er en fejl!", vbCritical, "Fejl"
            End Select
        Next
        MsgBox "slut!"
    End If
End Sub

Function event_handle(event_string, nr As Integer)
    Dim q
    q = Split(event_string, "##")
    event_handle = q(nr)
End Function

Function GetMouseEventInfo(saved_data, nr As Integer)
    Dim e
    e = Split(saved_data, ":")
    GetMouseEventInfo = e(nr)
End Function

Private Sub Command3_Click()
    If Command3.Caption = "Optag macro" Then
        StartTime = GetTickCount()
        KeysLogged = "" '** starter på ny optagelse
        Call HookKeyboard(Me) '** starter optagelsen
        Call SetMouseHook(Me)
        Command3.Caption = "Afbryd optagning!"
    Else
        Call UnHookKeyboard '** slukker for optagelsen
        Call UnMouseHook
        Command3.Caption = "Optag macro"
    End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Call UnHookKeyboard '** slukker for optagelsen
    Call UnMouseHook
End Sub

Public Sub API_MouseMove(X As Long, Y As Long)
    MouseX = X
    MouseY = Y
End Sub

Public Sub API_MouseEvent(button As String)
    KeysLogged = KeysLogged & "event-mus:" & MouseX & ":" & MouseY & ":" & button & "##" & (GetTickCount - StartTime)
    lstKey.AddItem "Mouse:    " & "X:" & MouseX & " Y:" & MouseY & " " & button
    StartTime = GetTickCount
End Sub

Function KeyGen(KeyAsciiCode As Integer)
    Dim q As String
    q = Chr(KeyAsciiCode)
    If q = "!" _
    Or q = "#" _
    Or q = "+" _
    Or q = "^" _
    Or q = "{" _
    Or q = "}" _
    Or q = " " _
    Or q = vbCrLf _
    Or q = vbCr _
    Or q = vbLf Then
        q = "{" & q & "}"
    End If
    KeyGen = q
    '** denne funktion forhindre misforståelserne der opstår ved
    '** at tegnene som ! ^ + osv. har betydninger som alt, control og shift, når de bruges med AutoItX
End Function

'** ;) code end ;) **
Avatar billede h7iws Nybegynder
14. august 2007 - 23:07 #11
Det er hverken pæn eller fejlfri kode, men er lidt presset fra nu af og så til efterårferien, har en del afleveringer, samt arbejde og så det programmering jeg laver for klubben.
Men håber det lever op til de krav du stiller, ellers må jeg jo bare tage mig sammen og så lave det ordentligt ;)

Mvh Emil
Avatar billede blueice Nybegynder
25. september 2007 - 08:27 #12
Den virker helt fint tak skal du have
Avatar billede h7iws Nybegynder
25. september 2007 - 18:22 #13
np, bare sig til hvis den er lidt buggy ... Så skal jeg nok lige tage mig sammen ! :)
Avatar billede blueice Nybegynder
21. september 2008 - 21:16 #14
Er der nogen der kan lave koden om til vb.net?

Da jeg har opgradet til .net virker overstående kode ikke mere :(
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester