begin process at 2008 07 05 14:10:32
1 205 182 membres
158 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : Récupérer tous les handles d'une application choisie dans une liste [ Archives / J'AI BESOIN D'AIDE !!!! :O ] (nitrique)

Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 09:53:48

nitrique
Bonjour à tous,

Je liste tous les processus actifs dans une liste (de la même manière que le gestionnaire des taches).

Ensuite, à partir du ProcessID de l'application choisie, j'aimerais récuperer tous les handles de ce processus (un handle correspond à un composant de l'application choisie, je me trompe ?),
pour me permettre de sélectionner un champs texte de cette application.
Je le fait de cette manière:
tabHandles: array [0..100] of integer; // Un HWND est un integer...
procedure TfrmMain.ListerHandles(pid: Cardinal);
var
  handles: TList;
  i: Integer;
  findWindowsStruct: TFindWindowsStruct;
begin
  handles:= TList.Create;
  Try
    findWindowsStruct.ProcessID:= pid; // GetCurrentProcessID
    findWindowsStruct.HandleList:= handles;
    EnumWindows(@EnumWindowsProc, Integer(@findWindowsStruct));
    cbThreads.Clear;
    for i:= 0 to handles.Count - 1 do begin
      cbThreads.Items.Add('Handle: '+IntToStr(Integer(handles[i])));
      tabHandles[i] := Integer(handles[i]);
    end;
    cbThreads.ItemIndex := 0;
  Finally
    handles.Free;
  end;
end;
Mais quand je teste les handles reçus avec un
PostMessage(tabHandles[cbThreads.ItemIndex]),WM_CHAR,sCar,0); // Simulation du copier
Rien ne se passe.

Par exemple, Si je fait:
myHandle := GetTopwindow(GetforegroundWindow); // Ca marche mais que pour notePad
PostMessage(myHandle,WM_CHAR,sCar,0);
Et que le focus est sur le notepad par exemple, handle est égal à 263014.

Mais si j'utilise la méthode de listage pour le notepad, il ne me retourne qu'un enregistrement qui est différent de celui de la solution ci-dessus (459614).

Comment faire ?

[;)] David, à VERSAILLES
[ Lien ]

Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 12:18:30

cirec
Membre Club
(Admin CS)
Salut,
Ce bout de code envoie du texte à la calculatrice


procedure TForm1.Button1Click(Sender: TObject);
Var s : String;
  H_WinCmd : THandle;
begin
S := '123456789'; // Texte à envoyer
H_WinCmd := FindWindowEx(FindWindow(Nil, 'calculatrice'), 0,'Edit', nil);  // on trouve le handle de l'edit
SendMessage(H_WinCmd,WM_SETTEXT,0,Longint(s)); //On Change le Texte
end;


@+
Cirec



Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 12:28:35

nitrique
Bonjour cirec,

C'est cool, je mettrais le ProcessId dans le premier paramètre mais seulement le 3ème paramètre m'est inconnu, je veux essayer avec tous les handles du processus.

N'y a t-il pas un équivalent qui attends un HWND plutot qu'un pchar en paramètre ?

[;)] David, à VERSAILLES
[ Lien ]

Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 13:33:04

cirec
Membre Club
(Admin CS)

Le handle que tu récupère ainsi c'est celui de la fenêtre et non celui d'un composant.
Pour pouvoir envoyer du texte au NotePad il faut trouver le handle de l'Edit qui se trouve sur la fiche


Voici une variante qui change le texte du Notepad
procedure
TForm1.Button1Click(Sender: TObject);
Var s : String;
  H_WinCmd : THandle;
begin
  S := '123456789'; // Texte à envoyer
  H_WinCmd := FindWindowEx(FindWindow('NotePad', Nil), 0,'edit', nil);  // on trouve le handle de l'edit
  SendMessage(H_WinCmd,WM_SETTEXT,0,Longint(s)); //On Change le Texte
end;

Pour énumerer les fenêtres enfants il existe :
EnumChildWindows
Essaye peut être avec mais il faudra quand même faire la différence entre un bouton et un edit pour envoyer le texte au bon composant

@+
Cirec

Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 13:40:58

nitrique
Très bien, je vais essayer.

Mais dans ce cas, comment ça se fait que ma fonction retourne plusieurs handles pour certains processus (word, ...) ?
De plus, dans le cas d'une application qui a plusieurs champs textes, j'aimerais choisir !

[;)] David, à VERSAILLES
[ Lien ]

Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 14:11:01

cirec
Membre Club
(Admin CS)
Pourrais-tu encore fournir les déclarations et implémentations de  : EnumWindowsProc & FindWindowsStruct
pour pouvoir faire un teste

@+
Cirec

Re : Récupérer tous les handles d'une application choisie dans une liste le 13/04/2006 14:28:55

nitrique

Aucun pb, les voici:
type
  PFindWindowsStruct = ^TFindWindowsStruct;
  TFindWindowsStruct = record
    ProcessID: DWORD;
    HandleList: TList;
var
  tabProcessus: array [1..100] of Cardinal; // Contient le ProcessId de la première comboBox
  tabHandles: array [0..100] of integer; // Contient les handles de la deuxième comboBox

function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): boolean; stdcall;
var
  dwProcessId: DWORD;
begin
  if lParam <> 0 then
  begin
    GetWindowThreadProcessId(hwnd, dwProcessId);
    with PFindWindowsStruct(lParam)^ do
      if dwProcessID = ProcessID then
        HandleList.Add(Pointer(hwnd));
    result:= true;
  end
  else
    result:= false;
end;

procedure TfrmMain.ListerProcessus(); // Lister les processus actifs du systeme
var
  SnapShot: Cardinal;
  ProcessEntry: TProcessEntry32;
  i: integer;
begin
  cbProcessus.Clear;
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // Création de "l'instantané"
  If SnapShot = 0 then Exit; // En cas d'erreur on sort
  ProcessEntry.dwSize := SizeOf(ProcessEntry);
  If Process32First(SnapShot, ProcessEntry) then begin // Lecture du premier processus de la liste
    cbProcessus.Items.Add(ProcessEntry.szExeFile);
    cbProcessus.ItemIndex := 0;
    i := 0;
    while Process32Next(SnapShot, ProcessEntry) do begin // Tant qu'il reste un processus, ajouter son nom à la liste
      cbProcessus.Items.Add(ProcessEntry.szExeFile+' ('+IntToStr(ProcessEntry.th32ProcessID)+')');
      i := i+1;
      tabProcessus[i] := ProcessEntry.th32ProcessID; // Garde le ProcessId pour la correspondance
     end;
  end;
  CloseHandle(SnapShot); // Libération de l'instantané
end;

procedure TfrmMain.ListerHandles(pid: Cardinal);
var
  handles: TList;
  i: Integer;
  findWindowsStruct: TFindWindowsStruct;
begin
  handles:= TList.Create;
  Try
    findWindowsStruct.ProcessID:= pid; // GetCurrentProcessID
    findWindowsStruct.HandleList:= handles;
    EnumWindows(@EnumWindowsProc, Integer(@findWindowsStruct));
    cbThreads.Clear;
    for i:= 0 to handles.Count - 1 do begin
      cbThreads.Items.Add(IntToStr(pid)+' '+IntToStr(Integer(handles[i])));
      tabHandles[i] := Integer(handles[i]);
    end;
    cbThreads.ItemIndex := 0;
  Finally
    handles.Free;
  end;
end;

procedure TfrmMain.cbProcessusChange(Sender: TObject);
begin
  ListerHandles(tabProcessus[cbProcessus.ItemIndex]);
end;

postMessage(tabHandles[cbThreads.ItemIndex],WM_PASTE,0,0); // Dans mon évenement

Il faut juste 2 combobox (cbProcessus et cbThreads)
Le principe est simple, quand tu changer cbProcessus qui contient le nom de tous les processus, j'aurais aimé que ça affiche tous les handles correspondant aux composants de ce processus dans la 2ème lookup.

[;)] David, à VERSAILLES
[ Lien ]


Re : Récupérer tous les handles d'une application choisie dans une liste le 14/04/2006 00:22:15

cirec
Membre Club
(Admin CS)
Réponse acceptée !

Bon alors regarde j'ai fait un bout de code, cette approche un peut différente mais c'est la seule qui me permet de faire l'inventaire des composants (plus où moins, ne fonctionne pas avec toutes les applications) et d'en selectionner un pour lui envoyer du texte :

Unit USendText;

Interface

Uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

Type
  TFrmMain = Class(TForm)
    cbProcessus: TComboBox;
    cbThreads: TComboBox;
    Edit1: TEdit;
    btn_Refresh: TButton;
    Procedure btn_RefreshClick(Sender: TObject);
    Procedure FormShow(Sender: TObject);
    Procedure FormClose(Sender: TObject; Var Action: TCloseAction);
    Procedure cbProcessusChange(Sender: TObject);
    Procedure cbThreadsClick(Sender: TObject);
    Procedure FormCreate(Sender: TObject);
  Private
    Procedure ListerChilds(pid: Cardinal);
    { Déclarations privées }
  Public
    { Déclarations publiques }
  End;

Function EnumWindowsProc(hWnd: HWND; lParam: lParam): Bool; stdcall;

Const
  aStr              = '%s %d';

Var
  FrmMain           : TFrmMain;
  HandleList        : TStringList;

Implementation

{$R *.DFM}
Uses TlHelp32;

Var
  tabProcessus        : Array[0..100] Of Cardinal;
    // Contient le ProcessId de la première comboBox
  tabHandles          : Array[0..100] Of integer;
    // Contient les handles de la deuxième comboBox

Function EnumWindowsProc(hWnd: HWND; lParam: lParam): Bool;
Var
  processID         : DWORD;
  aName             : Array[0..255] Of Char;
Begin
  GetWindowThreadProcessID(hwnd, @processID);
  If (hWnd <> FindWindow('Shell_TrayWnd', Nil)) And
    (hWnd <> FindWindow('Progman', Nil)) Then
    If IsWindowVisible(hwnd) Then
      Begin
        GetWindowText(hwnd, aName, SizeOf(aName));
        HandleList.Add(Format(aStr, [aName, HWnd]));
        TabProcessus[HandleList.Count - 1] := hwnd;
        Result := True;
      End;
End;

Procedure GetProcessList;
Begin
  HandleList.Clear;
  EnumWindows(@EnumWindowsProc, 0);
End;


Procedure TFrmMain.ListerChilds(pid: Cardinal);
Var aHandle         : THandle;
  aName             : Array[0..255] Of Char;
Begin
  cbThreads.Clear;
  aHandle := 0;
  Repeat
    aHandle := FindWindowEx(pid, aHandle, Nil, Nil);
    If aHandle <> 0 Then
      Begin
        GetClassName(aHandle, aName, SizeOf(aName));
        cbThreads.Items.Add(Format(aStr, [aName, aHandle]));
        tabHandles[cbThreads.Items.Count - 1] := aHandle;
      End;
  Until aHandle = 0;
End;

Procedure TfrmMain.cbProcessusChange(Sender: TObject);
Begin
  ListerChilds(TabProcessus[cbProcessus.ItemIndex]);
End;

Procedure TFrmMain.cbThreadsClick(Sender: TObject);
Var S               : String;
Begin
  S := '1234567890';
  SendMessage(tabHandles[cbThreads.ItemIndex], WM_SETTEXT, 0, Longint(s));
    //On Change le Texte
End;

Procedure TFrmMain.FormCreate(Sender: TObject);
Begin
  HandleList := TStringList.Create;
End;

Procedure TFrmMain.FormClose(Sender: TObject; Var Action: TCloseAction);
Begin
  HandleList.Free;
End;

Procedure TFrmMain.FormShow(Sender: TObject);
Begin
  btn_Refresh.Click;
End;

Procedure TFrmMain.btn_RefreshClick(Sender: TObject);
Begin
  GetProcessList;
  cbProcessus.Items.Clear;
  cbProcessus.Items.AddStrings(HandleList);
End;

End.

Le TEdit n'est la que pour tester et pour avoir FrmMain dans la liste il faut cliquer sur Refresh

Tester ok sur : NotePad, Calculatrice et sur lui même.

il faut bien sur affiner mais je pense que c'est la marche à suivre

Tiens moi au courant

@+
Cirec

Re : Récupérer tous les handles d'une application choisie dans une liste le 14/04/2006 10:43:32

nitrique
Heu...

Tu est sur que tout est la ?

Ma combobox de proccessus est vide, EnumWindows(@EnumWindowsProc, 0); ne remplit pas HandleList.

Ne faut-il pas garder ma fonction ListerProcessus() ?

[;)] David, à VERSAILLES
[ Lien ]

Re : Récupérer tous les handles d'une application choisie dans une liste le 14/04/2006 11:10:13

nitrique
En fait, il ne passe pas IsWindowVisible dans EnumWindowsProc.
Si j'enlève la condition, ça plante !

Quels élements cible tu en les voulant visibles ?
Ne peut-on pas utiliser ta méthode avec ma fonction ListerProcessus() ?

[;)] David, à VERSAILLES
[ Lien ]


[Page 1 Page 2]
Classé sous : application, liste, integer, choisie, handles

Participer à cet échange

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Redaction texte pour s...
Budget : 180€
Travail graphique- ill...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS