Keyboardhook

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Keyboardhook

Beitrag von uweb »

Hallo,
ich versuche gerade eine sehr einfach Arbeitserleichterung zu schreiben. Ein Keyboardhook soll bei "<" ZeichenfolgeA und bei ">" ZeichenfolgeB in das aktive Fremdfenster schreiben.
Die Basis dafür habe ich auch schnell hier gefunden : http://forums.purebasic.com/german/view ... 16&t=21363
Aber schon beim zweiten Dummy (beim ersten ging die Tastaturkombination nicht) brauche ich Hilfe.
Bei dem Code wird die Aktion meist zweimal ausgeführt. Manchmal sprngt der Cursor rauf und runter und manchmal markiere ich etwas wegen der Shift-Taste.

Code: Alles auswählen

;Diesen Code als Shared_Dll kompilieren
Global SHIFTpressed
ProcedureDLL KeyboardHook(nCode.l,wParam.l,lParam.l)
Protected Check.l=#True
If nCode=#HC_ACTION
 Select wParam
  Case #VK_SHIFT : SHIFTpressed = 1
  Case #VK_OEM_102
  If SHIFTpressed
    keybd_event_(#VK_UP,   #Null,#KEYEVENTF_EXTENDEDKEY,#Null)
  Else
    keybd_event_(#VK_DOWN, #Null,#KEYEVENTF_EXTENDEDKEY,#Null)
  EndIf
  Default : SHIFTpressed = 0 : Check=#False
 EndSelect
Else
 Check=#False
EndIf
Delay(500)
;
If Check : ProcedureReturn 1 : EndIf
ProcedureReturn CallNextHookEx_(@KeyboardHook(),nCode,wParam,lParam)
EndProcedure
Sorry falls jemand auf den ersten Dummy antworten wollte.

Den Code für die Exe habe ich aus dem Link (oben) 1:1 übernommen.

Code: Alles auswählen

EnableExplicit
;
#G_Txt=0
#G_Btn=1
#Lazy= 0
#Bizzy=1
#Lib=  0
#DLL_Name="MyKeyHook.dll" ;eventuell anpassen
#WinF=#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered
;
Prototype.l Proto_KeyHook(nCode.l,wParam.l,lParam.l)
Define.l Quit, Hooker
Define.l hMod, hHook
;
hMod=OpenLibrary(#Lib,#DLL_Name)
If Not hMod    : End : EndIf
Global KeyHook.Proto_KeyHook=GetFunction(#Lib,"KeyboardHook")
If Not KeyHook : End : EndIf
;
OpenWindow(0,0,0,200,80,"Hook",#WinF)
TextGadget(#G_Txt,10,10,180,20,"Kein Haken in der Tastatur.",#PB_Text_Center)
ButtonGadget(#G_Btn,50,40,100,20,"Haken rein !")
;
Repeat
 Select WaitWindowEvent()
  Case #PB_Event_Gadget
   If EventGadget()=#G_Btn
    Select Hooker
     Case #Lazy
      hHook=SetWindowsHookEx_(#WH_KEYBOARD,KeyHook,hMod,#Null)
      SetGadgetText(#G_Txt,"Tastatur hängt am Haken.")
      SetGadgetText(#G_Btn,"Haken raus !")
      Hooker!1
     Case #Bizzy
      UnhookWindowsHookEx_(hHook)
      SetGadgetText(#G_Txt,"Kein Haken in der Tastatur.")
      SetGadgetText(#G_Btn,"Haken rein !")
      Hooker!1
    EndSelect
   EndIf
  Case #PB_Event_CloseWindow : Quit!1
 EndSelect
Until Quit
;
If Hooker : UnhookWindowsHookEx_(hHook) : EndIf
End
;
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Keyboardhook

Beitrag von Kiffi »

IMO braucht es keinen Hook. Schau Dir mal
GetAsyncKeyState_() oder RegisterHotKey_() an.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: Keyboardhook

Beitrag von uweb »

Danke!

Die Suche wird wohl diesmal etwas aufwendiger.
Ich finde zwar viel, aber keine Out-of-the-Box-Lösung für Fremdfenster.
Ich melde mich mit der nächsten Frage oder der Lösung wieder.

Wenn aber jemand schon etwas in der Schublade liegen hat wäre ich auch nicht böse.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: Keyboardhook

Beitrag von uweb »

Ich habe keine Ahnung wo gestern mein Problem lag beim Kombinieren von RegisterHotKey() und keybd_event_().
Vermutlich hatte ich einen Flüchtigkeitsfehler. So selten wie ich dazu komme mich mit PB zu beschäftigen wäre das kein Wunder. Auf jeden Fall habe ich zu schnell aufgegeben und bin davon ausgegangen, dass es nicht geht.
Den letzten Zwischenstand von gestern habe ich nun durch die lauffähige Version ersetzt:

Code: Alles auswählen

EnableExplicit
Define EventID

Procedure SendKeys(Keys.s)
  Protected i.l, KeyCode.w, VirtualKey.b, KeysState.b

  For i = 1 To Len(Keys)
    KeyCode = VkKeyScan_(Asc(Mid(Keys,i,1)))
    VirtualKey = KeyCode & $FF
    KeysState = (KeyCode >> 8) & $FF
   
    Select KeysState
      Case 1 ; Umschalt-Taste wird benoetigt
        keybd_event_(#VK_SHIFT,1,0,0)
      Case 6 ; "Alt Groß"-Taste wird benoetigt
        keybd_event_(#VK_RMENU,1,0,0)
    EndSelect
   
    keybd_event_(VirtualKey,1,0,0)
    keybd_event_(VirtualKey,1,#KEYEVENTF_KEYUP,0)
   
    Select KeysState
      Case 1 ; Umschalt-Taste wieder loslassen
        keybd_event_(#VK_SHIFT,1,#KEYEVENTF_KEYUP,0)
      Case 6 ; "Alt Groß"-Taste wieder loslassen
        keybd_event_(#VK_RMENU,1,#KEYEVENTF_KEYUP,0)
    EndSelect
  Next
EndProcedure

If OpenWindow(0, 0, 0, 0, 0, "<>", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  RegisterHotKey_(WindowID(0), 1, #Null, #VK_OEM_102)
  RegisterHotKey_(WindowID(0), 2, #MOD_SHIFT, #VK_OEM_102)
  
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #WM_HOTKEY
      Select EventwParam()
        Case 1
          SendKeys ("eckige Klammer wurde blockiert")
        Case 2
          SendKeys ("Shift + eckige Klammer wurde blockiert")
        EndSelect
    EndIf
    If EventID = #PB_Event_CloseWindow
      UnregisterHotKey_(WindowID(0), 1)
      UnregisterHotKey_(WindowID(0), 2)
      End
    EndIf
  ForEver
EndIf
Danke Kiffi und Danke WinAPI Library (RSBasic und CoAutoren) !
Antworten