Tastaturcode umleiten

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Tastaturcode umleiten

Beitrag von dysti »

Hallo,
bei meinem Laptop ist die Tastatur defekt gewesen. Habe eine andere und jetzt stimmen die Tasten nicht.
Wie kann ich mit PB einen eigenen Tastaurtreiber programieren.
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

reion theoretisch würde ich als "scherzprog" die tastatur abfangen udn mit vkey andere tasten dafür "weiterleiten"
aber als treiber kann man das nicht sehen
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

a14xerus: Vkey ist leider nicht das was ich gemeint habe.

Habe kdrive32 ausfindig gemacht. Das Programm kann aber nur die normalen Tasten umbelegen. Die Shift- oder Strg-Tasten sind außen vor.
Es ist wirklich kein Spaß weshalb ich diese Frage hier eingestellt habe.
Die Enter-/Returntaste liegt auf meiner Laptoptastatur auf "p". Die Shifttaste auf "d" usw.
Mir geht es um folgendes:
1. kann ich mit PB ein Hintergrundprg. erstellen, was alle Tastencodes abfängt und durch andere ersetzt?
2. wie muß das Prg.-gerüst aussehen für so ein Hintergrundprg?
3. oder weiß jemand ein fertiges Prg. ähnlich kdrive32 nur das man alle Tasten kodieren kann?
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Vielleicht kannst du mit meinem kleinen Keylogger etwas anfangen und den
LowLevelKeyboardHook abändern.

Beenden kannst du ihn mit der Eingabe "keyhookende" irgendwo, egal in
welchem Fenster. Dann öffnet sich ein MessageRequester, in dem du das
Beenden noch bestätigen musst. Dann wird alles, was du geschrieben hast in
einer Datei im aktuellen Arbeitsverzeichnis gespeichert.

Schau dir einfach mal den Code an und werde draus schlau. :)

Eigentlich nichts für Anfänger!

Code: Alles auswählen

EnableExplicit

#ExitMsg = "keyhookende"

DataSection
  DS_vkCode:
    Data.s "", "LBUTTON", "RBUTTON", "CANCEL", "MBUTTON", "", "", "", "BACK", "TAB", "", "", "CLEAR", "RETURN", "", ""
    Data.s "SHIFT", "CONTROL", "MENU", "PAUSE", "CAPITAL", "", "", "", "", "", "", "ESCAPE", "", "", "", ""
    Data.s "SPACE", "PRIOR", "NEXT", "END", "HOME", "LEFT", "UP", "RIGHT", "DOWN", "SELECT", "PRINT", "EXECUTE", "SNAPSHOT", "INSERT", "DELETE", "HELP"
    Data.s "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "", "", "", "", "", ""
    Data.s "", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"
    Data.s "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "LWIN", "RWIN", "APPS", "", ""
    Data.s "NUMPAD0", "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD4", "NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9", "MULTIPLY", "ADD", "SEPARATOR", "SUBTRACT", "DECIMAL", "DIVIDE"
    Data.s "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16"
    Data.s "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "", "", "", "", "", "", "", ""
    Data.s "NUMLOCK", "SCROLL", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
    Data.s "LSHIFT", "RSHIFT", "LCONTROL", "RCONTROL", "LMENU", "RMENU", "", "", "", "", "", "", "", "", "", ""
    Data.s "", "", "", "", "", "", "", "", "", "", "OEM_1", "OEM_PLUS", "OEM_COMMA", "OEM_MINUS", "OEM_PERIOD", "OEM_2"
    Data.s "OEM_3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
    Data.s "", "", "", "", "", "", "", "", "", "", "", "OEM_4", "OEM_5", "OEM_6", "OEM_7", ""
    Data.s "", "", "", "", "", "PROCESSKEY", "", "", "", "", "", "", "", "", "", ""
    Data.s "", "", "", "", "", "", "ATTN", "CRSEL", "EXSEL", "EREOF", "PLAY", "ZOOM", "NONAME", "PA1", "OEM_CLEAR", ""
EndDataSection

Procedure.s GetvkCode(vkCode.l)
  Static loaded.l = #False
  Static Dim vkCodes.s(255)
  Protected a.l
  
  If loaded = #False
    Restore DS_vkCode
    For a = 0 To 255
      Read vkCodes(a)
    Next
    loaded = #True
  EndIf
  
  If vkCode < 0 Or vkCode > 255 : ProcedureReturn "" : EndIf
  ProcedureReturn vkCodes(vkCode)
EndProcedure

; /* Virtual key codes */
; /*                          0x05-0x07  Undefined */
; /*                          0x0A-0x0B  Undefined */
; /*                          0x0E-0x0F  Undefined */
; /*                          0x15-0x19  reserved For Kanji systems */
; /*                          0x1A       Undefined */
; /*                          0x1C-0x1F  reserved For Kanji systems */
; /*                          0x3A-0x40  Undefined */
; /*                          0x5E-0x5F  Unassigned */
; /*                          0x88-0x8F  Unassigned */
; /*                          0x92-0x9F  Unassigned */
; /*                          0xA6-0xB9  Unassigned */
; /*                          0xC1-0xDA  Unassigned */
; /*                          0xDF-0xE4  OEM specific */
; /*                          0xE6       OEM specific */
; /*                          0xE7-0xE8  Unassigned */
; /*                          0xE9-0xF5  OEM specific */

Global hWindow.l, msg.l, hook.l, Text.s, quitmsg.s

Structure KBDLLHOOKSTRUCT 
  vkCode.l
  scanCode.l
  flags.l
  time.l
  dwExtraInfo.l
EndStructure

Procedure.s DB_LCase(String.s)
  Static first.l = 0, Dim Chars.c(255)
  Protected *c.Character, a.l
 
  If first = 0
    For a = 0 To 255
      Select a
        Case 65 To 90
          Chars(a) = a + 32
        Case 138, 140, 142
          Chars(a) = a + 16
        Case 159
          Chars(a) = 255
        Case 192 To 214
          Chars(a) = a + 32
        Case 216 To 222
          Chars(a) = a + 32
        Default
          Chars(a) = a
      EndSelect
    Next
    first = 1
  EndIf
 
  *c = @String
  While *c\c
    If *c\c <= 255
      *c\c = Chars(*c\c)
    EndIf
    *c + SizeOf(Character)
  Wend
 
  ProcedureReturn String
EndProcedure
Procedure.s DB_UCase(String.s)
  Static first.l = 0, Dim Chars.c(255)
  Protected *c.Character, a.l
 
  If first = 0
    For a = 0 To 255
      Select a
        Case 48 : Chars(a) = '='
        Case 49 : Chars(a) = '!'
        Case 50 : Chars(a) = '"'
        Case 51 : Chars(a) = '§'
        Case 52 : Chars(a) = '$'
        Case 53 : Chars(a) = '%'
        Case 54 : Chars(a) = '&'
        Case 55 : Chars(a) = '/'
        Case 56 : Chars(a) = '('
        Case 57 : Chars(a) = ')'
        Case 46 : Chars(a) = ':'
        Case 44 : Chars(a) = ';'
        Case 45 : Chars(a) = '_'
        Case 97 To 122
          Chars(a) = a - 32
        Case 154, 156, 158
          Chars(a) = a - 16
        Case 255
          Chars(a) = 159
        Case 224 To 246
          Chars(a) = a - 32
        Case 248 To 254
          Chars(a) = a - 32
        Default
          Chars(a) = a
      EndSelect
    Next
    first = 1
  EndIf
 
  *c = @String
  While *c\c
    If *c\c <= 255
      *c\c = Chars(*c\c)
    EndIf
    *c + SizeOf(Character)
  Wend
 
  ProcedureReturn String
EndProcedure
Procedure.s MakeChar(wParam.l, *p.KBDLLHOOKSTRUCT)
  Protected ASCII.l = -1, z.s = ""
  Static shiftdown.l = #False, altdown.l = #False, ctrldown.l = #False, menudown.l = #False
  
  If wParam = #WM_KEYDOWN
    Select *p\vkCode
      Case #VK_A To #VK_Z
        ASCII = 97 + *p\vkCode - #VK_A
      Case #VK_0 To #VK_9
        ASCII = 48 + *p\vkCode - #VK_0
      Case #VK_LSHIFT, #VK_RSHIFT
        shiftdown = #True
      Case #VK_SPACE
        ASCII = 32
      Case #VK_RETURN
        ASCII = 13
      Case #VK_LCONTROL
        If ctrldown = #False : z = "{LCONTROL Down}" : EndIf
        ctrldown = #True
      Case #VK_RCONTROL
        If ctrldown = #False : z = "{RCONTROL Down}" : EndIf
        ctrldown = #True
      Case #VK_LMENU
        If menudown = #False : z = "{LMENU Down}" : EndIf
        menudown = #True
      Case #VK_RMENU
        If menudown = #False : z = "{RMENU Down}" : EndIf
        menudown = #True
      Case #VK_OEM_PLUS
        z = "+"
      Case #VK_OEM_MINUS
        z = "-"
      Case #VK_OEM_DIVIDE
        z = "/"
      Case #VK_OEM_MULTIPLY
        z = "*"
      Case #VK_LWIN
        z = "{LWIN}"
      Case #VK_RWIN
        z = "{RWIN}"
      Case 188
        ASCII = '.'
      Case 190
        ASCII = ','
      Case 222
        z = "ä"
      Case 192
        z = "ö"
      Case 186
        z = "ü"
      Case #VK_PRIOR
        z = "{PgUp}"
      Case #VK_NEXT
        z = "{PgDn}"
      Case 189
        z = "-"
      Default
        z = "{" + GetvkCode(*p\vkCode) + "}"
    EndSelect
    If ASCII <> -1
      z = Chr(ASCII)
      If shiftdown : z = DB_UCase(z) : EndIf
    EndIf
    ProcedureReturn z
  
  ElseIf wParam = #WM_KEYUP
    Select *p\vkCode
      Case #VK_LSHIFT, #VK_RSHIFT
        shiftdown = #False
      Case #VK_LCONTROL
        z = "{LCONTROL Up}"
        ctrldown = #False
      Case #VK_RCONTROL
        z = "{RCONTROL Up}"
        ctrldown = #False
      Case #VK_LMENU
        z = "{LMENU Up}"
        menudown = #False
      Case #VK_RMENU
        z = "{RMENU Up}"
        menudown = #False
    EndSelect
    ProcedureReturn z
    
  ElseIf wParam = #WM_SYSKEYDOWN
    If altdown = #False : z = "{ALT Down}" : EndIf
    altdown = #True
    ProcedureReturn z
  ElseIf wParam = #WM_SYSKEYUP
    altdown = #False
    ProcedureReturn "{ALT Up}"
  EndIf
EndProcedure

Procedure.l LowLevelKeyboardProc(nCode.l, wParam.l, lParam.l) 
  Protected *p.KBDLLHOOKSTRUCT = lParam, rz.s
  If nCode = #HC_ACTION 
    rz = MakeChar(wParam, *p)
    If rz <> ""
      Text + rz
      quitmsg = Right(quitmsg + rz, Len(#ExitMsg))
      Debug quitmsg
    EndIf
  EndIf 
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam) 
EndProcedure 

Procedure Exit() 
  If MessageRequester("EXIT", "KeyboardHook beenden?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure 

Define SystemPath.s, hIcon.l

#WH_KEYBOARD_LL = 13 
If SetWindowsHookEx_(#WH_KEYBOARD_LL, @LowLevelKeyboardProc(), GetModuleHandle_(0), 0) = 0 : End : EndIf

msg = RegisterWindowMessage_("DKs_k8D_h00K")

Repeat 
  If WaitWindowEvent(100) = #PB_Event_CloseWindow : Break : EndIf
  If quitmsg = #ExitMsg
    quitmsg = ""
    If Exit() : Break : EndIf
  EndIf
ForEver

Define File.s

File.s = GetCurrentDirectory() + FormatDate("LOG_%yyyy-%mm-%dd_%hh-%ii-%ss_" + MD5Fingerprint(@Text, Len(Text)) + ".txt", Date())
If CreateFile(0, File)
  WriteString(0, Text)
  CloseFile(0)
EndIf

UnhookWindowsHookEx_(hook)
End
Benutzeravatar
Karl
Beiträge: 520
Registriert: 21.07.2005 13:57
Wohnort: zu Hause

Beitrag von Karl »

@NTQ: Sieht interessant aus. Hast du irgendwo mehr Informationen zu Hooks & Co. (pdf, html etc.)? Könnte bei einer Textbausteinverwaltung helfen.

Gruß Karl
The Kopyright Liberation Front also known as the justified ancients of Mumu!
PB 5.X
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Nein, hab ich alles aus der MSDN und diversen Codes, die ich per Google-Codesearch
gefunden habe, zusammengebastelt.

Aber das meiste ich eigentlich von hier: MSDN - SetWindowsHookEx Function
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

@NTQ: Das sieht gut aus. Ich denke, ich kann den Code lesen. Somit habe ich schon mal das Gerüst. Den Rest werde ich schon hinbekommen.
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
Sanders
Beiträge: 4
Registriert: 17.07.2007 10:08

Beitrag von Sanders »

@ntq ich bekomme beim starten immer folgende Meldung
"Line 179 - Constant not found: #VK_OEM_PLUS"

warum, mache ich was flasch oder ...... :|
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Beitrag von c4s »

Sanders hat geschrieben:@ntq ich bekomme beim starten immer folgende Meldung
"Line 179 - Constant not found: #VK_OEM_PLUS"

warum, mache ich was flasch oder ...... :|
Ersetzte einfach
#VK_OEM_PLUS -> 187
#VK_OEM_MINUS -> 189
#VK_OEM_DIVIDE -> 111
#VK_OEM_MULTIPLY -> 106
dann müsste es funktionieren.
(wobei du es auch einfach zum testen ausklammern könntest)
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Sanders
Beiträge: 4
Registriert: 17.07.2007 10:08

Beitrag von Sanders »

danke c4s
das funtzt :D
Antworten