Page 1 sur 1

Hook clavier global

Publié : dim. 05/juil./2009 18:18
par nico
Voici un code mettant en place un Hook clavier global, tout ce que vous tapez dans n'importe quelle application est intercepté par le programme.

Programme:

Code : Tout sélectionner

#Librairie=0
#WM_MONMESSAGE= #WM_USER+1

Structure Partage
  Hook.l
  HandleApplication.l
  HandleFocusClavier.l
  ActiverHook.l  
EndStructure

Global *Vue.Partage

Procedure ProcedureCallback(WindowID.l, Message.l, wParam.l, lParam.l)
  
  Resultat = #PB_ProcessPureBasicEvents
  Select Message
    Case #WM_MONMESSAGE
      ;Si wParam >0, alors on à un code ascii sinon c'est ue touche système
      If wParam>0
        ;Code ascii
        AddGadgetItem(0,-1,Chr(wParam))
      Else
        ;Code virtuel de la touche
        AddGadgetItem(0,-1,"Code virtuel de la touche="+Str(lParam))
      EndIf 
      

  EndSelect
  ProcedureReturn Resultat
EndProcedure


If OpenWindow(0,0,0,200,200,"Capture du clavier",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_TitleBar)
  
  EditorGadget(0,10,10,180,140,#PB_Editor_ReadOnly)
  ButtonGadget(1,50,160,100,30,"Quitter")
  SetWindowCallback(@ProcedureCallback())
  
  StickyWindow(0,1)
  
  Hmodule = OpenLibrary(#Librairie,"Hook_Clavier_Global_dll.dll")
  If Hmodule=0
    MessageRequester("Info","La Dll (Hook_Clavier_Global_dll.dll) n'a pu être chargée!, le programme va se terminer")
    End
  EndIf 
  
  *Vue=CallFunction(#Librairie, "Initialiser_Hook", WindowID(0),Hmodule)
  If *Vue=0
    MessageRequester("Info","L'installation du Hook a échoué!, le programme va se terminer")
    End
  EndIf 
  
  
  Repeat
    Event = WaitWindowEvent()
    Select event
      Case #PB_Event_Gadget 
        Select EventGadget()
          Case 1
            Quit=1
        EndSelect 
        
      Case #WM_CLOSE
        Quit=1
    EndSelect 
    
  Until Quit=1
  
  If *Vue<>0
    If CallFunction(#Librairie, "Fermeture_Hook")=0
      MessageRequester("Info","La désinstallation du Hook à échoué!")
    EndIf 
  EndIf
  
EndIf

la DLL, à compiler sous le nom de Hook_Clavier_Global_dll.dll:

Code : Tout sélectionner

#WM_MONMESSAGE= #WM_USER+1

Structure Partage
  Hook.l
  HandleApplication.l
  HandleFocusClavier.l
  ActiverHook.l     
EndStructure


Global MemoirePartagee.l,*Vue.Partage
Global Dim Key.b(255)


Procedure.l Keyboard_Hook(nCode.l, wParam.l, lParam.l)
  ;Quel que soit le type de hook, La valeur nCode doit toujours être vérifiée
  ;car si elle est inférieur à 0, il faut passer l'évènement à la procédure
  ;d'interception suivante.
  
  If nCode < 0
    ProcedureReturn CallNextHookEx_(*Vue\Hook, nCode, wParam, lParam)
  EndIf
  
  If *Vue\ActiverHook=#True
    If nCode=#HC_ACTION
      If lParam & 2147483648=0 ;(Test du bit 31= 2^31  0 si enfoncé, 1 si relaché)
        ;
        Ascii.w=0
        GetKeyboardState_(@Key(0))
        
        ;Le paramètre wparam renvoie le code virtuel de la touche
        ;pour le convertir en Ascii si c'est un caractère, on utilise cette fonction
        ToAscii_(wParam,(lParam>>16) & $FF ,@Key(0),@Ascii,0)
        
        ; Control ayant le focus clavier
        *Vue\HandleFocusClavier=GetFocus_()

        PostMessage_(*Vue\HandleApplication,#WM_MONMESSAGE,Ascii, wParam)

      EndIf 
    EndIf
  EndIf   
  ProcedureReturn CallNextHookEx_(*Vue\Hook, nCode, wParam, lParam)
EndProcedure

ProcedureDLL AttachProcess(Instance.l)
  MemoirePartagee=CreateFileMapping_($FFFFFFFF,#Null, #PAGE_READWRITE, 0, SizeOf(Partage),"Mapping")
  *Vue=MapViewOfFile_(MemoirePartagee, #FILE_MAP_WRITE, 0, 0, 0)
EndProcedure

ProcedureDLL DetachProcess(Instance.l)
  UnmapViewOfFile_(VueDonnees)
  CloseHandle_(MemoirePartagee)
EndProcedure
 
ProcedureDLL AttachThread(Instance.l)
EndProcedure
 
ProcedureDLL DetachThread(Instance.l)
EndProcedure
 
ProcedureDLL.L Initialiser_Hook(Handle.l,Hinst.l)
  Protected Hook.l
  *Vue\HandleApplication=Handle
  Hook.l = SetWindowsHookEx_(#WH_KEYBOARD,@Keyboard_Hook(),Hinst,0)
  If Hook = #False
    ProcedureReturn 0
  EndIf
  *Vue\Hook=Hook
  *Vue\ActiverHook=#True
  ProcedureReturn *Vue
EndProcedure   

ProcedureDLL.l Fermeture_Hook()
  Protected Result.l
  Result.l= UnhookWindowsHookEx_(*Vue\Hook)
  ProcedureReturn Result
EndProcedure

Publié : dim. 05/juil./2009 18:19
par nico
J'en ai profiter pour en faire un programme complet téléchargeable ici: SpeedTexte.zip

Ce programme qui se loge dans le systray, permet de remplacer des abréviations par du texte, exemple:
Click droit sur l'icone, et cliquer sur le menu: Editer le fichier des Abréviations
Dans le champ Abréviation, entrez par exemple:mr
Dans le champ Remplacer par, entrez: MessageRequester("","")
Cliquer sur Ajouter
Cliquer sur le bouton: Enregistrer et Quitter

Maintenant à chaque fois que vous taperez mr, ce mot sera remplacer par MessageRequester("","")

L'application supporte les variables, par exemple:
si vous écrivez comme abréviation: mr remplacer par Messagerequester("$$1","$$2")
et que vous taper mr$Info, $$1 sera remplacer par Info et le résultat sera MessageRequester("Info","") et le curseur se positionnera entre les deux guillemets

Si vous tapez mr$Info$Purebasic, le résultat sera MessageRequester("Info","Purebasic")

Si vous souhaitez ajouter des espaces, il faut les remplacer par le caractère ":", exemple:
mr$Info$Programme:Purebasic donnera MessageRequester("Info","Programme Purebasic")

Publié : dim. 05/juil./2009 18:49
par Backup
Merci ! :)

excellent comme d'hab !! :)

tres utile pour msn également :)

Publié : dim. 05/juil./2009 19:16
par nico
Je viens d'uploder le fichier SpeedTexte.zip, le code ne marchait pas!

Publié : dim. 05/juil./2009 19:22
par comtois
Je viens de tester, ça fonctionne très bien, excellent !

Merci pour le code.

Publié : lun. 06/juil./2009 8:53
par Kwai chang caine
Encore un de nos eminents membres qui se fait trop rare sur le forum :cry:

Pour le code c'est super utile
Merci..... 8)

Publié : lun. 06/juil./2009 9:13
par djes
Top :)