- 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:
D'abord la gestion du Hook clavier
1 2 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 ...
1 2 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.
1 2 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]
1 2 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 ...
1 2 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