Eigenen Tastatur Treiber programmieren
Re: Eigenen Tastatur Treiber programmieren
Achso ok aber ich verstehe nur Bahnhof bzw ich kriegs nicht hin. Kannst du mir helfen? Das ist so komlex ich steig nicht durch.
Re: Eigenen Tastatur Treiber programmieren
Hier der funktionierende Code:
DLL-Datei:
EXE-Datei:
Was passiert genau?
DLL-Datei:
Code: Alles auswählen
EnableExplicit
ProcedureDLL KeyboardProc(code, wParam, lParam)
#WM_GETKEY = #WM_USER + 1024
Global WindowID
If code < 0
ProcedureReturn CallNextHookEx_(@KeyboardProc(), code, wParam, lParam)
EndIf
If WindowID = 0
WindowID = FindWindow_(0, "MultiKBHook")
EndIf
If WindowID
If SendMessage_(WindowID, #WM_GETKEY, wParam, lParam) = #True
ProcedureReturn -1
EndIf
EndIf
ProcedureReturn CallNextHookEx_(@KeyboardProc(), code, wParam, lParam)
EndProcedure
Code: Alles auswählen
EnableExplicit
#RID_HEADER = $10000005
#RID_INPUT = $10000003
#RIM_TYPEMOUSE = 0
#RIM_TYPEKEYBOARD = 1
#RIM_TYPEHID = 2
#RIDEV_REMOVE = $00000001
#RIDEV_EXCLUDE = $00000010
#RIDEV_PAGEONLY = $00000020
#RIDEV_NOLEGACY = $00000030
#RIDEV_INPUTSINK = $00000100
#RIDEV_CAPTUREMOUSE = $00000200
#RIDEV_NOHOTKEYS = $00000200
#RIDEV_APPKEYS = $00000400
#RIDEV_EXINPUTSINK = $00001000
#RIDEV_DEVNOTIFY = $00002000
#RIDI_PREPARSEDDATA = $20000005
#RIDI_DEVICENAME = $20000007
#RIDI_DEVICEINFO = $2000000b
#WM_GETKEY = #WM_USER + 1024
Prototype GetRawInputData(hRawInput, uiCommand, *pData.RAWINPUT, *pcbSize, cbSizeHeader)
Prototype RegisterRawInputDevices(*pRawInputDevices.RAWINPUTDEVICE, *uiNumDevices, cbSize)
Prototype GetRawInputDeviceList(*pRawInputDeviceList.RAWINPUTDEVICELIST, *uiNumDevices, cbSize)
Prototype GetRawInputDeviceInfo(hDevice, uiCommand, *pData, *pcbSize)
Global user32 = OpenLibrary(#PB_Any, "user32.dll")
If IsLibrary(user32)
Global RegisterRawInputDevices.RegisterRawInputDevices = GetFunction(user32, "RegisterRawInputDevices")
Global GetRawInputData.GetRawInputData = GetFunction(user32, "GetRawInputData")
Global GetRawInputDeviceList.GetRawInputDeviceList = GetFunction(user32, "GetRawInputDeviceList")
Global GetRawInputDeviceInfo.GetRawInputDeviceInfo = GetFunction(user32, "GetRawInputDeviceInfoW")
EndIf
Import "kernel32.lib"
GetProcAddress(hModule, lpProcName.p-ascii)
EndImport
Global HookID
Global MultiKBHook
Global LasthDevice
Procedure WindowCallback(WindowID, Message, wParam, lParam)
Protected result = #PB_ProcessPureBasicEvents
Protected Key
Protected VirtualCode
Protected RepeatCount
Protected ScanCode
Protected SpecialKey
Protected AltState
Protected PreviousState
Protected KeyUp
Select Message
Case #WM_GETKEY
Key=lParam
VirtualCode=wParam
RepeatCount=Key&$FFFF
ScanCode=(Key>>16)&$FF
SpecialKey=(Key>>24)&1
AltState=(Key>>29)&1
PreviousState=(Key>>30)&1
KeyUp=Key>>31&1
result = #False
If LasthDevice = 99354541;Handle der Tastatur
If ScanCode = 30;Buchstabe A
result = #True
Debug "funktioniert"
Else
result = #False
EndIf
EndIf
Case #WM_INPUT
Protected pcbSize.l
Protected *pRawData.RAWINPUT
If GetRawInputData(lParam, #RID_INPUT, #Null, @pcbSize, SizeOf(RAWINPUTHEADER)) = 0
*pRawData = AllocateMemory(pcbSize)
If *pRawData
GetRawInputData(lParam, #RID_INPUT, *pRawData, @pcbSize, SizeOf(RAWINPUTHEADER))
Select *pRawData\header\dwType
Case #RIM_TYPEKEYBOARD
LasthDevice = *pRawData\header\hDevice;lieber danach GetRawInputDeviceInfo() benutzen
EndSelect
FreeMemory(*pRawData)
EndIf
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 500, 400, "MultiKBHook", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowCallback(@WindowCallback())
Dim Rid.RAWINPUTDEVICE(0)
Rid(0)\usUsagePage = 1
Rid(0)\usUsage = 0
Rid(0)\hwndTarget = WindowID(0)
Rid(0)\dwFlags = #RIDEV_INPUTSINK | #RIDEV_PAGEONLY
RegisterRawInputDevices(@Rid(), ArraySize(Rid()) + 1, SizeOf(RAWINPUTDEVICE))
MultiKBHook = OpenLibrary(0, "MultiKBHook.dll")
If MultiKBHook
HookID = SetWindowsHookEx_(#WH_KEYBOARD, GetProcAddress(MultiKBHook, "KeyboardProc"), MultiKBHook, 0)
If HookID = 0
Debug "Hook konnte nicht erstellt werden."
EndIf
Else
Debug "Die DLL-Datei konnte nicht gefunden werden."
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
UnhookWindowsHookEx_(HookID)
CloseLibrary(0)
CloseLibrary(user32)
End
EndSelect
ForEver
EndIf
- Das Programm lädt die DLL-Datei und ruft die DLL-Funktion "KeyboardProc" für die Erstellung des globalen Keyboard-Hooks auf.
- Bei beliebiger Eingabe wird an das Fenster des Hauptprogramms eine benutzerdefinierte Windows-Message mit den Parametern gesendet und wartet auf den Rückgabewert und bei #true gibt er anschließend -1 für das Blocken der Weitergabe der Taste zurück.
- Im Hauptprogramm wird gleichzeitig im Hintergrund die Tastatur-Quelle ermittelt und die Handle-Nummer der Tastatur in die Variable LasthDevice geschrieben. Da ist es zukünftig besser, wenn du zusätzlich GetRawInputDeviceInfo() aufrufst um die Tastatur-Hardware-Informationen auszulesen, um deine Tastaturen besser zu unterschieden. Zum Testen habe ich hier nur einen Handle-Vergleich gemacht.
- Im Windows-Callback des Hauptprogramms kam nun die von der DLL-Datei gesendete Windows-Message an und wird auf Tastatur-Quelle und auf den gedrückten Tastenwert überprüft. Bei "A" soll beispielhaft geblockt werden. Also soll der Rückgabewert = #true sein.
- DLL-Datei blockt nun mit Hilfe des Hooks die Weitergabe der Taste.
Re: Eigenen Tastatur Treiber programmieren
Hallo!
Das hier:
funktioniert auch "GLOBAL".
Das hier:
Code: Alles auswählen
Global ende.b = #False, i.i
Repeat
For i = 0 To 255
If GetAsyncKeyState_(i) >= 255
;Debug i
MessageRequester("Keyboard-Test", "VK: "+Str(i)+" gedrückt.",#MB_SYSTEMMODAL)
If i = 13 Or i = 27 ;Enter oder ESC führen zum Abbruch
ende = #True
Break
EndIf
EndIf
Next i
Until ende = #True
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: Eigenen Tastatur Treiber programmieren
@rsbasic
Danke dass du extra für mich umgesetzt hast. Ich habe die Tastatur Nummer ID vorher ausgegeben und dann in der IF eingetragen und es funktioniert. Danke du hast mir extrem geholfen!!
@ccode_new
Danke für den Code und ich dachte zuerst es ginge mit deinem Code deutlich kürzer aber wie kann ich mit deinem Code sagen dass er eine bestimmte Taste nicht ausführen soll? Dh ich drücke die Taste A und ich fange die Taste ab und sage Nein und unterdrücke es so dass der Buchstabe A nicht in einem anderen Programm wie Notepad erscheint. Klappt es mit deinem Code irgendwie? Das wäre super!
Danke dass du extra für mich umgesetzt hast. Ich habe die Tastatur Nummer ID vorher ausgegeben und dann in der IF eingetragen und es funktioniert. Danke du hast mir extrem geholfen!!
@ccode_new
Danke für den Code und ich dachte zuerst es ginge mit deinem Code deutlich kürzer aber wie kann ich mit deinem Code sagen dass er eine bestimmte Taste nicht ausführen soll? Dh ich drücke die Taste A und ich fange die Taste ab und sage Nein und unterdrücke es so dass der Buchstabe A nicht in einem anderen Programm wie Notepad erscheint. Klappt es mit deinem Code irgendwie? Das wäre super!
Re: Eigenen Tastatur Treiber programmieren
(ツ)_/(Hallo!)
|__|
| |
Richte dich da lieber an den Windows-Api-Meister (RSBasic).
Ich hätte da nur einen unschönen Trick:
|__|
| |
Da hast du recht!¯\_(ツ)_/¯ hat geschrieben:@ccode_new
Danke für den Code und ich dachte zuerst es ginge mit deinem Code deutlich kürzer aber wie kann ich mit deinem Code sagen dass er eine bestimmte Taste nicht ausführen soll? Dh ich drücke die Taste A und ich fange die Taste ab und sage Nein und unterdrücke es so dass der Buchstabe A nicht in einem anderen Programm wie Notepad erscheint. Klappt es mit deinem Code irgendwie? Das wäre super!
Richte dich da lieber an den Windows-Api-Meister (RSBasic).
Ich hätte da nur einen unschönen Trick:
Code: Alles auswählen
EnableExplicit
Global ende.b = #False, z.i
; SendInput-Anpassungsfunktion von Hier->(https://www.purebasic.fr/english/viewtopic.php?p=289971) geklaut. ;)
Global Dim SendInputData.INPUT(0) ;Structure INPUT ist vordefiniert!
Procedure SendPrepare(n,VK,Char,UpDown,*Resize=#Null)
SendInputData(n)\Type=#INPUT_KEYBOARD
SendInputData(n)\ki\wVk=VK
SendInputData(n)\ki\time=0
SendInputData(n)\ki\dwExtraInfo=0
SendInputData(n)\ki\wScan=Char
SendInputData(n)\ki\dwFlags=UpDown
If *Resize
n=PeekL(*Resize)+1
PokeL(*Resize,n)
ReDim SendInputData(n)
EndIf
EndProcedure
Procedure SendInput(Text.s)
#KEYEVENTF_UNICODE = 4
Protected i.l; Pointer to Character in the Text
Protected j.l; Counter for SendInput
Protected k.l; Total Size for SendInput
Protected Char.l
Protected NewChar.l
Protected KeyDown.l
k=Len(Text)*2 ;*2 wegen Unicode!
If k
ReDim SendInputData(k)
While j < k
PokeS(@NewChar,Chr(PeekB(@Text+i)),#PB_Unicode)
If (newchar=char) And KeyDown
KeyDown=#False
SendPrepare(j,0,Char,#KEYEVENTF_UNICODE|#KEYEVENTF_KEYUP,@k)
Else
char=newchar
KeyDown=#True
If char=13
SendPrepare(j,#VK_MENU,0,#KEYEVENTF_EXTENDEDKEY,@k)
SendPrepare(j,#VK_RETURN,0,#KEYEVENTF_EXTENDEDKEY)
SendPrepare(j,#VK_MENU,0,#KEYEVENTF_KEYUP,@k)
Else
SendPrepare(j,0,Char,#KEYEVENTF_UNICODE)
EndIf
i+1
EndIf
j+1
Wend
SendInput_(k,SendInputData(0),SizeOf(INPUT))
Delay(500) ;Wir warten! (Sonst werden zu viele Tastschläge simuliert)
EndIf
EndProcedure
Repeat
For z = 0 To 255
If GetAsyncKeyState_(z) >= 255
;Debug i
;MessageRequester("Keyboard-Test", "VK: "+Str(i)+" gedrückt.", #MB_SYSTEMMODAL)
If z = 65 ;A - Taste gedrückt
SendInput(Chr(8)) ;Backspace !!!
;Die Nachricht der Taste 'A' wird nicht blockiert und nicht umbelegt. (Machbar entweder aber über Einschubmethode (HOOK), oder Registry)
SendInput("Das ist unsinniger Mist, aber trotzdem toll!")
Continue
;...
EndIf
If z = 27 ;ESC führt zum Abbruch
MessageRequester("Keyboard-Test", "Keyboard-Test beendet", #MB_SYSTEMMODAL)
ende = #True
Break
EndIf
EndIf
Next z
Until ende = #True
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat