- 1 ListBox en haut
   - 1 Bouton Clear
   - 1 SpeedButton "Enfonçable" avec les propriétés GroupIndex=1, AllowUp=true,Caption="Activé"
   - 1 ActionList avec 3 actions : ActiveHook,DeActiveHook,GetWindowInfo
   
   puis  : pour tester la partie 2 ( action sur les controls )
            -6 TEdit : 
                         EDT_WINDOWTITLE (titre de la fenetre parente),
                         EDT_EXENAME         (nom de l'executable )
                         EDT_CONTROLNAME (titre du Control)
                         EDT_CLASSE            (classe/type du control)
                         EDT_RANG               (rang/numero du control dans sa fenetre parente)
                         EDT_NEWTEXT        (texte à envoyer dans le control)
            -1 Bouton: BTN_SENDTEXT
 Code de l'outil : 1ère partie : Analyse:
Code de l'outil : 1ère partie : Analyse: 
D'abord la gestion du Hook clavier
	
	| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 
 | //---------------------------------------------------------------------------
// Code source libre 
// par Djob.
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
#include "psapi.h"        //<- ajouter C:\...CBuilder6\\Lib\Psdk\psapi.lib au projet
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HHOOK hHook;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
/*---------------------------------------------------------------------------
  PARTIE I . CREATION DE L'OUTIL PERMETTANT LA RECUPERATION DES INFORMATIONS
             CONCERNANT LES CONTROLS PLACES DANS UNE AUTRE APPLICATION
  ---------------------------------------------------------------------------
*/
 
/*   --------------------------------------------------------------------------
     FONCTION DU HOOK CLAVIER :
     ( interception des touches clavier en dehors de l'executable )
     si la barre d'espace est préssé (en mode activé) on récupere les
     informations du control ou de la fenetre placée en dessous
     du curseur de la souris.
     --------------------------------------------------------------------------
*/
 
__declspec(dllexport) LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam, LPARAM lParam)
{
        if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
        {
        KBDLLHOOKSTRUCT hookstruct = *((KBDLLHOOKSTRUCT*)lParam);
        DWORD vkCode = hookstruct.vkCode;
 
          // si on appuie sur la touche espace..
         //  on déclenche la récupération des informations du control 
        //   sous la souris....
 
          if(vkCode==VK_SPACE){   
             Form1->ActGetWindowInfo->Execute();
          }
        }
        return CallNextHookEx(hHook, nCode, wParam, lParam);
}
 
/* ---------------------------------------------------------------------------
     ACTION Activer la Détection Clavier
   ---------------------------------------------------------------------------
*/
void __fastcall TForm1::ActActiveHookExecute(TObject *Sender)
{
        BTN_HOOK->Caption="Désactiver";
        HWND hExe= GetModuleHandle(NULL);//Application->Handle;
        hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC) HookProc, hExe, NULL);
}
/* ---------------------------------------------------------------------------
     ACTION Désactiver la Détection Clavier
   ---------------------------------------------------------------------------
*/
void __fastcall TForm1::ActDeActiveHookExecute(TObject *Sender)
{
        UnhookWindowsHookEx(hHook);
        BTN_HOOK->Caption="Activer";
}
/* ---------------------------------------------------------------------------
   BTN_HOOK (Activer/Désactiver): speedbutton enfonçable : propriété Groupindex=1, Allowup=true
   ---------------------------------------------------------------------------
*/
void __fastcall TForm1::BTN_HOOKClick(TObject *Sender)
{
        if(BTN_HOOK->Down){
            ActActiveHook->Execute();
        }else{
            ActDeActiveHook->Execute();
        }
} | 
 .... Puis les fonctions de récupération des informations :
une fonction pour récuperer le rang/numéro du control dans sa fenetre
parente ...
	
	| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 |  
/* ---------------------------------------------------------------------------
   FONCTION QUI RETOURNE LE NUMERO (SON RANG) DU CONTROL DANS SA FENETRE OU
   SON CONTROL PARENT.
   ---------------------------------------------------------------------------
*/
int __fastcall GetControlNumber(HWND ParentWindow,HWND ControlToFind){
 
     HWND hCurrentControl=NULL;
     int pos=0;
     do{
       pos++;
       hCurrentControl=FindWindowEx(ParentWindow,hCurrentControl,NULL,NULL);
       if(hCurrentControl== ControlToFind) return pos;
 
     }while(hCurrentControl!=NULL);
     pos=-1;
     return pos;
 
} | 
 ... Une fonction pour retrouver le nom de l'executable associé au control pointé par la souris:
Cela va nous permettre d'avoir 2 paramètres pour retrouver une fenetre:
son titre et l'executable qui l'a produite.
	
	| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 |  
/* ---------------------------------------------------------------------------
   FONCTION QUI RETOURNE LE CHEMIN DE L'EXCUTABLE ASSOCIE AU CONTROL
   ---------------------------------------------------------------------------
*/
String __fastcall GetExePath(HWND AWindow){
 
           DWORD ProcessID;
           GetWindowThreadProcessId(AWindow,&ProcessID);
           char file_path[MAX_PATH];
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, ProcessID);
           if(hProcess!=0){
              GetModuleFileNameEx(hProcess,0,file_path,MAX_PATH);
              CloseHandle(hProcess);
              String ExeName(file_path);
              return ExeName;
           }else{
              CloseHandle(hProcess);
              return "";
           }
} | 
 [Edit : ajout]  Ajout d'une fonction qui calcule de dégré d'encastrement du control :  i.e : un Edit dans un Panel lui même posé sur une fiche : 
                  degré=2;
      Ce parametre vous sert à controler de combien vous allez  descendre en profondeur pour allez chercher le Handle du control : si le Panel a comme numero d'ordre 3, et l'Edit 2 dans le Panel ,  il vous faudra trouver le Handle du rang 2, du Handle du Rang 3, du Handle de la fenetre ...etc..

[/Edit]
	
	| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 |  
/*
   ---------------------------------------------------------------------------
   FONCTION TEST DE PROFONDEUR  / ENCASTREMENT DANS UN AUTRE CONTROL
   // niveau 0 : Fiche, 1 : composants de premier plan
   ---------------------------------------------------------------------------
*/
int __fastcall GetProfondeur(HWND AControl){
        if(AControl==NULL) return -1;
        HWND hCurrControl=AControl;
        int deep = -1;
        do{
             hCurrControl= GetParent(hCurrControl);
           deep++;
        }while( hCurrControl!=NULL);
        return deep;
} | 
 Voici l'action qui est déclenchée quand on tape sur la barre d'espace et que le Hook est activé....
Cette action permet de retrouver le Handle du control placé sous la souris
grace à l'api WindowFromPoint.. et d'en déduire le texte,la classe, le rang, la position de ce control ...
	
	| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 
 |  
/* ---------------------------------------------------------------------------
   ACTION : RETROUVER LES INFORMATIONS ET LES INCRIRE DANS LA LISTBOX
   ---------------------------------------------------------------------------
*/
void __fastcall TForm1::ActGetWindowInfoExecute(TObject *Sender)
{
        TPoint  Pt;
        HWND  AHandle;  //Handle du Control trouve
        DWORD ProcessID; // ID du Process
        String ListBoxLineInfo;
        int rang; // rang du control dans sa fenetre parent
 
        // on récupere les coordonnées pointées par le curseur
        if (GetCursorPos(&Pt)){
 
           // On Recupere le Handle du Control ou de la fenetre situé en
           // dessous du curseur.
           AHandle = WindowFromPoint(Pt);
 
           //on en déduit son Parent
           HWND hParentWindow = GetParent(AHandle);
 
           //on récupère le titre de la fenetre ou du control
           char WindowCaption[255];
           GetWindowText(AHandle,WindowCaption,255);
           ListBoxLineInfo = "Caption  : "+ String(WindowCaption);
           ListBox1->Items->Add(ListBoxLineInfo);
 
           //on récupère le type  du control (le nom de la classe : TEdit,TComboBox)
 
           char ClassName[255];
           GetClassName(AHandle,ClassName,255);
           ListBoxLineInfo = "Classe : "+ String(ClassName);
           if(hParentWindow!=NULL){
                   rang =  GetControlNumber(hParentWindow,AHandle);
                   if(rang!=-1)
                     ListBoxLineInfo +=" / N°(rang): "+IntToStr(rang);
           }
           ListBox1->Items->Add(ListBoxLineInfo);
 
           //on récupère la profondeur ( encastrement dans d'autre control)
           int profondeur = GetProfondeur(AHandle);
           ListBoxLineInfo = "Profondeur/encastrement : "+ IntToStr(profondeur);
           ListBox1->Items->Add(ListBoxLineInfo);
 
 
           //on récupère l' id du thread
 
           GetWindowThreadProcessId(AHandle,&ProcessID);
           ListBoxLineInfo = "ID du processus : "+IntToStr(ProcessID);
           ListBox1->Items->Add(ListBoxLineInfo);
 
           //on récupère nom de l'executable associé
 
           String ExeName= GetExePath(AHandle);
           ListBoxLineInfo = "Chemin de l'executable : "+ExeName;
           ListBox1->Items->Add(ListBoxLineInfo);
           ListBoxLineInfo = "Nom de l'executable : "+ExtractFileName(ExeName);
 
           //on récupère l' id du control
 
           int ControlId=GetDlgCtrlID(AHandle);
           if(ControlId==0){
               ListBoxLineInfo = "ID Control : non attribué";
           }else{
               ListBoxLineInfo = "ID Control : "+IntToStr(ControlId) ;
           }
 
           ListBox1->Items->Add(ListBoxLineInfo);
 
           //poisition, taille:
 
           TRect RectPos;
           GetWindowRect(AHandle,&RectPos);
           ListBoxLineInfo = "Height = "+IntToStr(RectPos.Height());
           ListBox1->Items->Add(ListBoxLineInfo);
           ListBoxLineInfo = "Width = "+IntToStr(RectPos.Width());
           ListBox1->Items->Add(ListBoxLineInfo);
 
           TPoint  APoint;
           APoint.x=RectPos.Left;
           APoint.y=RectPos.Top;
 
           if(hParentWindow!=NULL){
 
               ::ScreenToClient(hParentWindow,&APoint);
           }
           ListBoxLineInfo = "Top    = "+IntToStr(APoint.x);
           ListBox1->Items->Add(ListBoxLineInfo);
           ListBoxLineInfo = "Left   = "+IntToStr(APoint.y);
           ListBox1->Items->Add(ListBoxLineInfo);
           ListBox1->Items->Add("");
 
           //ça c'est juste pour toujours voir le bas de la listbox
           SendMessage(ListBox1->Handle, WM_VSCROLL, SB_BOTTOM, 0 );
 
 
           /* --------pour la partie 2 uniquement-------------
            je reporte des derniers résultats  dans des Edits
            (parce ce que je suis paresseux et je melange le code
             de test avec le code de l'outil : ( bouh c po bien !)
            //////////////////////////////////////////////////
           ---------------------------------------------------
           */
           EDT_CONTROLNAME->Text = String(WindowCaption);
           //titre de la fenetre parente
           if(hParentWindow!=NULL){
                GetWindowText(hParentWindow,WindowCaption,255);
                EDT_WINDOWTITLE->Text = String(WindowCaption);
           }
           EDT_CLASSE->Text = String(String(ClassName));
           EDT_EXENAME->Text= ExtractFileName(ExeName);
           EDT_RANG->Text = IntToStr( rang);
           //------------------------------------------------
 
         }
}
//---------------------------------------------------------------------------
// JUSTE UN BOUTON POUR EFFACER LA LISTBOX
void __fastcall TForm1::BTN_CLEARClick(TObject *Sender)
{
        ListBox1->Clear();
}
//--------------------------------------------------------------------------- | 
 Utilisation : Activer ,pointer le control voulu et appuyer sur la barre d'espace:
        NB: ATTENTION!  On Suppose ici que les Controls sont directements
                        posés sur la Fenetre.
                        Si le control est enfermé dans un Panel ou Autre
                        il faudra chercher d'abors de Handle du Panel et rechercher
                        ensuite les control ayant comme parent le Handle du Panel..
      NB(2): !!!ATTENTION au Handle du Control pointé par l'outil pour les combobox
      Si la ComboBox est de type csDropDownList (non editable)  : pas de problème
      Par Contre si elle est ded type csDropDown (éditable) :
      il faut pointer la souris sur le bouton avec la fleche pour obtenir
      le Handle de la Combobox..
      L'autre zone désigne une Edit qui appartient à la Combobox,
      et vous trouverez comme rang : 1 ...car son parent est la combobox...
			
		
 
	
Partager