Seite 1 von 2

Tastaturausgaben global ändern?

Verfasst: 05.06.2007 00:14
von S3b
Wie kann ich, wenn ich Taste A drücke, global - egal in welchem Fenster,
statt Taste A, Taste B als 'output' ausgeben?
..dass wenn ich z.b. b drücke, q statt b kommt
Thx im Vorraus

Verfasst: 05.06.2007 00:26
von ts-soft

Verfasst: 05.06.2007 07:51
von hardfalcon
Stichwort "KeybaordHook" (wies in dem andern Thread ja auch schon gefallen ist). Da gibts sogar 2 hübsche Codes zu im Codearchiv...

http://purearea.net/pb/CodeArchiv/Input ... _F1-F12.pb
http://purearea.net/pb/CodeArchiv/Input ... rd_Hook.pb

Verfasst: 05.06.2007 11:29
von S3b
@ts-soft: habe vergessen zu sagen dass ich ein Programm dafür schreiben möchte..
@hardfalcon: thx aber wie mach ich jetzt

wenn drück b
kommen(q)
?

Verfasst: 05.06.2007 14:49
von TomS
Ich hab den Code "F1-F12 Sperren" mit der SendKeys-Funktion (glaube auch von Danilo) kombiniert.

Man müsste halt dann noch zusätzlich überprüfen ob eine der Shift-Tasten gedrückt wurde, denn jetzt wird "Q" gesendet auch wenn man ein kleines "b" drückt.

Viel Spaß damit.

Code: Alles auswählen

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=495
; Author: Danilo (updated for PB 4.00 by Andre)
; Date: 07. April 2003
; OS: Windows
; Demo: No

; Man findet im Systray ein Icon um den Hook zu beenden.
;
; Dieser LowLevel Keyboard Hook ist, falls mich jetzt nicht alles
; täuscht, undokumentiert - aber auch sonst ohne Gewähr.
;
; by Danilo, 07.04.2003 - german forum
;


Procedure SendKeys(handle,window$,keys$) 
If window$<>"" : handle=FindWindow_(0,window$) : EndIf ; Use window$ instead of handle. 
   If IsWindow_(handle)=0 ; Does the target window actually exist? 
      ProcedureReturn 0 ; Nope, so report 0 for failure to type. 
   Else 
   ; This block gives the target window the focus before typing. 
   thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0) 
   thread2=GetWindowThreadProcessId_(handle,0) 
   If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#True) : EndIf 
      SetForegroundWindow_(handle) ; Target window now has the focus for typing. 
      Delay(125) ; 1/8 second pause before typing, to prevent fast CPU problems. 
      ; Now the actual typing starts. 
      For r=1 To Len(keys$) 
          vk$=Mid(keys$,r,1) 
          If vk$="{" ; Special key found. 
             s=FindString(keys$,"}",r+1)-(r+1) ; Get length of special key. 
             s$=Mid(keys$,r+1,s) ; Get special key name. 
             Select s$ ; Get virtual key code of special key. 
                Case "ALTDOWN" : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down. 
                Case "ALTUP" : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT. 
                Case "BACKSPACE" : vk=#VK_BACK 
                Case "CONTROLDOWN" : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down. 
                Case "CONTROLUP" : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL. 
                Case "DELETE" : vk=#VK_DELETE 
                Case "DOWN" : vk=#VK_DOWN 
                Case "END" : vk=#VK_END 
                Case "ENTER" : vk=#VK_RETURN 
                Case "F1" : vk=#VK_F1 
                Case "F2" : vk=#VK_F2 
                Case "F3" : vk=#VK_F3 
                Case "F4" : vk=#VK_F4 
                Case "F5" : vk=#VK_F5 
                Case "F6" : vk=#VK_F6 
                Case "F7" : vk=#VK_F7 
                Case "F8" : vk=#VK_F8 
                Case "F9" : vk=#VK_F9 
                Case "F10" : vk=#VK_F10 
                Case "F11" : vk=#VK_F11 
                Case "F12" : vk=#VK_F12 
                Case "ESCAPE" : vk=#VK_ESCAPE 
                Case "HOME" : vk=#VK_HOME 
                Case "INSERT" : vk=#VK_INSERT 
                Case "LEFT" : vk=#VK_LEFT 
                Case "PAGEDOWN" : vk=#VK_NEXT 
                Case "PAGEUP" : vk=#VK_PRIOR 
                Case "PRINTSCREEN" : vk=#VK_SNAPSHOT 
                Case "RETURN" : vk=#VK_RETURN 
                Case "RIGHT" : vk=#VK_RIGHT 
                Case "SHIFTDOWN" : shifted=1 : keybd_event_(#VK_SHIFT,0,0,0) ; Hold SHIFT down. 
                Case "SHIFTUP" : shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT. 
                Case "TAB" : vk=#VK_TAB 
                Case "UP" : vk=#VK_UP 
             EndSelect 
             If Left(s$,3)<>"ALT" And Left(s$,7)<>"CONTROL" And Left(s$,5)<>"SHIFT" 
                keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the special key. 
             EndIf 
             r=r+s+1 ; Continue getting the keystrokes that follow the special key. 
          Else 
             vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character. 
             keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character. 
          EndIf 
      Next 
      If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf ; Finished typing to target window! 
      keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key if user forgot. 
      keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key if user forgot. 
      keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key if user forgot. 
      ProcedureReturn 1 ; Report successful typing! :) 
   EndIf 
EndProcedure 

Global hWindow,msg,hook

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

Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
  If nCode = #HC_ACTION
    If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN Or wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
      #LLKHF_ALTDOWN = $20
      If *p\vkCode = #VK_B And wParam=#WM_KEYDOWN      
            SendKeys(GetForegroundWindow_(),"","Q")  
        ProcedureReturn 1
      EndIf
    EndIf
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure

Procedure AskForExit()
  If MessageRequester("EXIT", "End the KeyboardHook ??",#MB_YESNO) = #IDYES
    UnhookWindowsHookEx_(hook) : End
  EndIf
EndProcedure

; Win NT
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf

hWindow     = OpenWindow(1,0,0,10,10,"k8D h00K",#PB_Window_Invisible)


; by daniel, 21. Nov 2002 (german Tips&Tricks)
SystemPath$ = Space(1024) : GetSystemDirectory_(SystemPath$,1024)
hIcon       = ExtractIcon_(0,SystemPath$+"\user32.dll",1)
;-----


AddSysTrayIcon(1,WindowID(1),hIcon)
SysTrayIconToolTip(1,"k8D h00K")
msg = RegisterWindowMessage_("DKs_k8D_h00K")

If CreatePopupMenu(0)
  For a = 1 To 19
    MenuItem(a, "Oink! - "+RSet(Str(a),2,"0"))
  Next a
  MenuBar()
  MenuItem(20,"QUIT IT!")
EndIf


Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow : End
    Case msg
      DisplayPopupMenu(0, hWindow,GetSystemMetrics_(#SM_CXSCREEN)/2,GetSystemMetrics_(#SM_CYSCREEN)/2)
    Case #PB_Event_Menu
      If EventMenu() = 20
        AskForExit()
      Else
        MessageRequester("MENU","Menu entry: "+Str(EventMenu()),0)
      EndIf
    Case #PB_Event_SysTray
      If EventType() = #PB_EventType_LeftDoubleClick
        AskForExit()
      EndIf
  EndSelect
ForEver



Verfasst: 05.06.2007 16:19
von Andreas_S
Ich sehe du hast mit keybd_event_() gearbeitet... warum :? ?

Es ist doch besser das event zu verändern als aufzuhalten!

Code: Alles auswählen

ProcedureReturn CallNextHookEx_(hook,nCode,wParam,*p\vkCode) 

Verfasst: 05.06.2007 19:24
von S3b
thx :]]


Habe mal hier was aus dem Prog. kopiert..:

Code: Alles auswählen

Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT) 
  If nCode = #HC_ACTION 
    If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN Or wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP 
      #LLKHF_ALTDOWN = $20 
      If *p\vkCode = #VK_B And wParam=#WM_KEYDOWN      
            SendKeys(GetForegroundWindow_(),"","Q")

; wenn ich hier
;
ElseIf *p\vkCode = #VK_A And wParam=#WM_KEYDOWN      
            SendKeys(GetForegroundWindow_(),"","E")
;  eingebe, kommt wenn ich b drücke "BQ" 

        ProcedureReturn 1 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p) 
EndProcedure 
& geaendert

(siehe Kommentarzeilen)
Wie kann ich das ändern?

thx im Vorraus :mrgreen:

Verfasst: 06.06.2007 00:08
von TomS
@PBprogger:
Die Sendkeys Funktion is nicht von mir, sondern ausm Code-Archiv (hab nur keine Ahnung mehr welche genau, das war von den vielen... Deswegen hab ich keinen Link).
Mir is klar, dass das nicht das Non-Plus-Ultra ist, aber ich hab zu wenig Api-Erfahrung um das besser zu machen. Wenn du weißt, wie man das Event ändert anstatt es aufzuhalten und neu zu senden, dann bin ich auf deinen Code gespannt.

@S3B:
Guckst du meinen Kommentar... (der mit den vielen "!!!")

Code: Alles auswählen

Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
  If nCode = #HC_ACTION
    If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN Or wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
      #LLKHF_ALTDOWN = $20
      If *p\vkCode = #VK_B And wParam=#WM_KEYDOWN     
            SendKeys(GetForegroundWindow_(),"","Q")
            ProcedureReturn 1 ;!!!!!!!!!!! Das is wichtig, nach jeder SendKeys()!!!!!!

; wenn ich hier
;
ElseIf *p\vkCode = #VK_A And wParam=#WM_KEYDOWN     
            SendKeys(GetForegroundWindow_(),"","E")
;  eingebe, kommt wenn ich b drücke "BQ"

        ProcedureReturn 1
      EndIf
    EndIf
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure
OK: Habs getestet. Funzt einwandfrei

Und jetzt noch was für die Api-Freaks:

Code: Alles auswählen

Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
  If nCode = #HC_ACTION
    If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN Or wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
      #LLKHF_ALTDOWN = $20

Debug *p\vkCode

      If *p\vkCode = #VK_A And wParam=#WM_KEYDOWN     
            SendKeys(GetForegroundWindow_(),"","Z")
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_Z And wParam=#WM_KEYDOWN     
            SendKeys(GetForegroundWindow_(),"","B")
            ProcedureReturn 1 

      EndIf
    EndIf
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure
Lustigerweise gibt der Debugger jetzt einmal "65" aus, dann 32 mal "90" und dann noch einmal "65". Und dann "66"
Das "90" kommt daher, weil ich ein "Z" senden will, wenn "A" gedrückt wird. Es werden also auch die gesendeten Tasten abgefangen. Deswegen kommt auch "66" vor, weil wenn man "Z" drückt ja schließlich "B" gesendet wird.
Und "B" ist es auch, das schlussendlich beim aktiven Fenstern ankommt.

Und das nervt ziemlich, da eine entgegengesetze Reihe (a>z, b>y ... y>b, z>a) dazu führt, dass a>a, b>b ... y>y, z>z

Das geht soweit, dass mein

Code: Alles auswählen

 If *p\vkCode = #VK_A And wParam=#WM_KEYDOWN
            keybd_event_(#VK_B, 0, 0, 0)    
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_B And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_C, 0, 0, 0)             
            ProcedureReturn 1 

            ;usw usw usw, will hier Platz sparen^^

      ElseIf *p\vkCode = #VK_Y And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_Z, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_Z And wParam=#WM_KEYDOWN 
            keybd_event_(#VK_A, 0, 0, 0)      
            some_var=0       
            ProcedureReturn 1 
      EndIf 
Ein "I" sendet, wenn ein "A" gedrückt wird. Und das "A" wird gesendet, wenn man "S" drückt.
Dieses Verhalten macht diese Funktion unberechenbar und ich frage mich, wie man Abhilfe schaffen könnte...

Danke schonmal

Verfasst: 06.06.2007 09:48
von real
Schau auf meiner Webseitenach dem Quellcode von KeybLock... Das Programm macht genau das, was Du möchtest. Wenn z.B. die linke Windows-Taste gedrückt wird, gibt das Programm 'O' zurück.

Aber grds. ist es oben schon beschrieben.

Verfasst: 06.06.2007 14:08
von TomS
Das macht mein Programm auch, nur leider nicht, wenn ich auf "O" auch ne andere Taste lege.

Mir scheint, wir verwenden sie selbe Source.
Dein Code funktioniert auch nur einwandfrei, wenn man auf "O" keine andere Taste legt.

Hier is nochmal mein kompletter Code

Code: Alles auswählen

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=495
; Author: Danilo (updated for PB 4.00 by Andre)
; Date: 07. April 2003
; OS: Windows
; Demo: No

; Man findet im Systray ein Icon um den Hook zu beenden.
;
; Dieser LowLevel Keyboard Hook ist, falls mich jetzt nicht alles
; täuscht, undokumentiert - aber auch sonst ohne Gewähr.
;
; by Danilo, 07.04.2003 - german forum


Global hWindow,msg,hook

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

Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
  If nCode = #HC_ACTION
    If wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN Or wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP
      #LLKHF_ALTDOWN = $20
      If *p\vkCode = #VK_A And wParam=#WM_KEYDOWN
            keybd_event_(#VK_Z, 0, 0, 0)    
            ProcedureReturn 1      
      ElseIf *p\vkCode = #VK_B And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_C, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_C And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_D, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_D And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_E, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_E And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_F, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_F And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_G, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_G And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_H, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_H And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_I, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_I And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_J, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_J And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_K, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_K And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_L, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_L And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_M, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_M And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_N, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_N And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_O, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_O And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_P, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_P And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_Q, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_Q And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_R, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_R And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_S, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_S And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_T, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_T And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_U, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_U And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_V, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_V And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_W, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_W And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_X, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_X And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_Y, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_Y And wParam=#WM_KEYDOWN           
            keybd_event_(#VK_Z, 0, 0, 0)             
            ProcedureReturn 1 
      ElseIf *p\vkCode = #VK_Z And wParam=#WM_KEYDOWN 
            keybd_event_(#VK_A, 0, 0, 0)      
            some_var=0       
            ProcedureReturn 1 
      
      EndIf 
      
      
    EndIf
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure

Procedure AskForExit()
  If MessageRequester("EXIT", "End the KeyboardHook ??",#MB_YESNO) = #IDYES
    UnhookWindowsHookEx_(hook) : End
  EndIf
EndProcedure

; Win NT
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf

hWindow     = OpenWindow(1,0,0,10,10,"k8D h00K",#PB_Window_Invisible)


; by daniel, 21. Nov 2002 (german Tips&Tricks)
SystemPath$ = Space(1024) : GetSystemDirectory_(SystemPath$,1024)
hIcon       = ExtractIcon_(0,SystemPath$+"\user32.dll",1)
;-----


AddSysTrayIcon(1,WindowID(1),hIcon)
SysTrayIconToolTip(1,"k8D h00K")
; msg = RegisterWindowMessage_("DKs_k8D_h00K")
; 
; If CreatePopupMenu(0)
;   For a = 1 To 19
;     MenuItem(a, "Oink! - "+RSet(Str(a),2,"0"))
;   Next a
;   MenuBar()
;   MenuItem(20,"QUIT IT!")
; EndIf
; 

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow : End
    Case msg
      DisplayPopupMenu(0, hWindow,GetSystemMetrics_(#SM_CXSCREEN)/2,GetSystemMetrics_(#SM_CYSCREEN)/2)
    Case #PB_Event_Menu
      If EventMenu() = 20
        AskForExit()
      Else
        MessageRequester("MENU","Menu entry: "+Str(EventMenu()),0)
      EndIf
    Case #PB_Event_SysTray
      If EventType() = #PB_EventType_LeftDoubleClick
        AskForExit()
      EndIf
  EndSelect
ForEver