Aktuelle Zeit: 17.09.2019 19:02

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: Eigenen Tastatur Treiber programmieren
BeitragVerfasst: 27.09.2018 22:22 
Offline

Registriert: 18.08.2017 09:35
Achso ok aber ich verstehe nur Bahnhof bzw ich kriegs nicht hin. Kannst du mir helfen? Das ist so komlex ich steig nicht durch.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Eigenen Tastatur Treiber programmieren
BeitragVerfasst: 27.09.2018 23:41 
Offline
Admin
Benutzeravatar

Registriert: 05.10.2006 18:55
Wohnort: Deutschland::Berlin()
Hier der funktionierende Code:

DLL-Datei:
Code:
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


EXE-Datei:
Code:
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


Was passiert genau?
  1. Das Programm lädt die DLL-Datei und ruft die DLL-Funktion "KeyboardProc" für die Erstellung des globalen Keyboard-Hooks auf.
  2. 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.
  3. 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.
  4. 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.
  5. DLL-Datei blockt nun mit Hilfe des Hooks die Weitergabe der Taste.

Ich hoffe, das war verständlich genug. Jetzt endlich ins Bett. :D

_________________
BildBildBildBild BildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Eigenen Tastatur Treiber programmieren
BeitragVerfasst: 27.09.2018 23:52 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
Hallo!

Das hier:
Code:
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


funktioniert auch "GLOBAL".


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Eigenen Tastatur Treiber programmieren
BeitragVerfasst: 28.09.2018 09:00 
Offline

Registriert: 18.08.2017 09:35
@rsbasic
:shock: :o 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. :o 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!

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Eigenen Tastatur Treiber programmieren
BeitragVerfasst: 28.09.2018 18:49 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
(ツ)_/(Hallo!)
|__|
| |

¯\_(ツ)_/¯ 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!


Da hast du recht!

Richte dich da lieber an den Windows-Api-Meister (RSBasic).

Ich hätte da nur einen unschönen Trick:

Code:
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


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ]  Gehe zu Seite Vorherige  1, 2

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  
cron

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye