IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Bouger une fenêtre en passant par les processus (sans FindWindow)


Sujet :

API, COM et SDKs Delphi

  1. #1
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut Bouger une fenêtre en passant par les processus (sans FindWindow)
    Bonjour,

    Voici maintenant 3 jours que je planche sur le même sujet, à savoir récupérer le Handle d'une application style FireFox afin de pouvoir la déplacer comme bon me semble avec un MoveWindow. En effet, je voudrais bouger les fenêtre mais sans quel soit au premier plan, et sans passer par un FindWindow car je ne connais pas forcément sa classe ni son nom de barre de titre.

    Ce sujet est en relation avec mon post sur Récupérer le moniteur sur lequel se trouve une fenêtre/application.

    Le but, c'est de lister les processus, regarder si ils ont une fenêtre (les services, et autres, je m'en occupe pas) et de pouvoir intéragir sur le bon Handle pour y appliquer mon MoveWindow.
    J'ai fait un bout de code, mais ça ne fonctionne pas
    J'ai encore du mal avec les fonctions API (ça tombe, je n'utilise pas les bonnes).
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    126
    127
    128
    129
    130
    131
    132
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,TlHelp32,Math ;
     
    type
      PFindWindowsStruct = ^TFindWindowsStruct;
      TFindWindowsStruct = record
        ProcessID: DWORD;
        HandleList: TList;
      end;
     
     TProcessInformations = record
       ProcessID : DWORD;
       ProcessHandle : THandle;
     end;
     
     
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        GroupBox1: TGroupBox;
        GroupBox2: TGroupBox;
        StaticText1: TStaticText;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        StaticText2: TStaticText;
        StaticText3: TStaticText;
        Label4: TLabel;
        StaticText4: TStaticText;
        GroupBox3: TGroupBox;
        Button2: TButton;
        Label5: TLabel;
        Label6: TLabel;
        Edit2: TEdit;
        Edit3: TEdit;
        Label7: TLabel;
        Label8: TLabel;
        Edit4: TEdit;
        Edit5: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    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 FindProcessWindows(ProcessID: Integer; Handles: TList);
    var
      findWindowsStruct: TFindWindowsStruct;
    begin
      findWindowsStruct.ProcessID:= ProcessID;
      findWindowsStruct.HandleList:= Handles;
      EnumWindows(@EnumWindowsProc, Integer(@findWindowsStruct));
    end;
     
    function getProcessID(const ProcessName : string) : TProcessInformations;
    var ProcessEntry32 : TProcessEntry32;
        HSnapShot : THandle;
        HProcess : THandle;
    begin
      Result.ProcessID := 0;
      Result.ProcessHandle := INVALID_HANDLE_VALUE;
     
      HSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      if HSnapShot = 0 then exit;
     
      ProcessEntry32.dwSize := sizeof(ProcessEntry32);
      if Process32First(HSnapShot, ProcessEntry32) then
      repeat
        if CompareText(ProcessEntry32.szExeFile, ProcessName) = 0 then
        begin
          HProcess := OpenProcess(PROCESS_TERMINATE, False, ProcessEntry32.th32ProcessID);
          Result.ProcessHandle := HProcess;
          Result.ProcessID := ProcessEntry32.th32ProcessID;
          CloseHandle(HProcess);
          Break;
        end;
      until not Process32Next(HSnapShot, ProcessEntry32);
      CloseHandle(HSnapshot);
    end;
     
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
     handles: TList;
     i : integer;
    begin
      handles:= TList.Create;
        try
          FindProcessWindows(getProcessID(Edit1.Text).ProcessID, handles);
          for i := 0 to handles.Count - 1 do
          begin
            if(IsWindow(Integer(handles[i])))then
              MoveWindow (Integer(handles[i]),StrToInt(Edit2.Text),StrToInt(Edit3.Text),StrToInt(Edit4.Text),StrToInt(Edit5.Text),true);
          end;
        finally
          handles.Free;
        end;
    end;
     
    end.
    J'espère que vous pourrez m'indiquer les bonnes directions dans lesquelles je dois chercher...
    Merci par avance

    Ero

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 758
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 758
    Points : 13 354
    Points
    13 354
    Par défaut
    Il me semble que tu prends le problème à l'envers .

    Ce sont les fenêtres qui t'intéresent. Utilise plutôt EnumWindows. Si ensuite tu as vraiment besoin du processus, GetWindowThreadProcessId ou GetWindowModuleFileName pour le nom de l'exe.

    EDIT:
    En fait, je vois que tu les utilises
    Mais quel est le but ? Retrouver toutes les fenêtres d'un processus particulier ?

  3. #3
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Il me semble que tu prends le problème à l'envers .

    Ce sont les fenêtres qui t'intéresent. Utilise plutôt EnumWindows. Si ensuite tu as vraiment besoin du processus, GetWindowThreadProcessId ou GetWindowModuleFileName pour le nom de l'exe.
    Ah!

    Donc, il faut que j'utilise EnumWindows qui va me permettre de lister toutes les fenêtres que j'ai à l'écran, c'est bien ça ?
    Bon, si je comprends bien, pour utiliser EnumWindows, je dois lui passer une adresse de fonction :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    Parameters

    lpEnumFunc
    [in] Pointer to an application-defined callback function. For more information, see EnumWindowsProc.
    lParam
    [in] Specifies an application-defined value to be passed to the callback function.
    Return Value

    If the function succeeds, the return value is nonzero.

    If the function fails, the return value is zero. To get extended error information, call GetLastError.

    If EnumWindowsProc returns zero, the return value is also zero. In this case, the callback function should call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
    Cette méthode utilise donc EnumWindowsProc que je dois définir moi même ... Et c'est dans cette méthode que je pourrais tester le nom du processus alors ?
    Le cas qui m'interesse tout d'abord, c'est de réussir avec Firefox
    Aussi, on n'est pas obligé que la fenêtre soit affiché sur l'écran , si ?
    Si elle est réduite dans la barre des tâches (et systray peut-être), on ça devrait fonctionner ?

    Désolé de poser toutes ces questions, mais faut bien un début à tout, et là, j'avoue que je patoge un petit peu.

    Merci pour ton aide

    [EDIT]
    Mon but est de bouton dire :
    Toi, la fenêtre firefox, bouge à telle position, et redimensionne toi à cette taille. Comme tu dis, j'ai peut-être pris le problème à l'envers car je pars du processus pour déterminer le Handle de l'application (et non du processus).
    Car MoveWindow attend un Handle de fenêtre, hors, avec FireFox, j'y arrive pas
    En fait, à terme ça serait de récupérer toutes les fenêtres des applications pour intéragir sur chacune d'elle sur le placement et le redimensionnement.
    Par exemple, je regarde les process qui tourne :
    Ah, tient, y a FF, IE, MSN, ...., je vais prendre leurs coordonnées écrans pour un traitement que je ferai plus tard

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 758
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 758
    Points : 13 354
    Points
    13 354
    Par défaut
    En gros, c'est ça
    Attention à ne pas oublier le StdCall.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function EnumWindowsCallback(aWnd: hWnd; lParam: integer): boolean; stdcall;
    begin
      ...
      Result := TRUE; //TRUE pour continuer
    end;
     
    EnumWindows(@EnumWindowsCallback, 0);
    Aussi, on n'est pas obligé que la fenêtre soit affiché sur l'écran , si ?
    Si elle est réduite dans la barre des tâches (et systray peut-être), on ça devrait fonctionner ?
    Je pense qu'il n'y a pas de problème, mais a essayer.

  5. #5
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    En gros, c'est ça
    Attention à ne pas oublier le StdCall.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function EnumWindowsCallback(aWnd: hWnd; lParam: integer): boolean; stdcall;
    begin
      ...
      Result := TRUE; //TRUE pour continuer
    end;
     
    EnumWindows(@EnumWindowsCallback, 0);


    Je pense qu'il n'y a pas de problème, mais a essayer.
    Je te remercie,
    Je teste ça ce week end si j'ai le temps et je te tiens au courant

    Merci pour ton apport d'infos

  6. #6
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    J'ai réussi à faire la moitié de la chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,Tlhelp32;
     
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    // donne, à partir du handle d'une fenêtre, l'exécutable à l'origine de cette fenêtre
    function GetProcessNameFromHandle(Handle:HWND):string;
    var
      Pid:DWord;
      SnapShot:HWND;
      Module:TModuleEntry32;
    begin
      Result:='';
      if not IsWindow(Handle) then exit;
      GetWindowThreadProcessId(Handle,@Pid); // récupere le pid
      Snapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,Pid); // creer un snapshot sur le pid
      try
        if Snapshot<>-1 then
        begin
          Module.dwSize:=SizeOf(TModuleEntry32);
          if Module32First(Snapshot,Module) then  result:=Module.szExePath; // recupere l'exe path
        end;
      finally
        CloseHandle(Snapshot);
      end;
    end;
     
     
    function EnumWindowsCallback(aWnd: hWnd; lParam: integer): boolean; stdcall;
    var Texte:array[0..250]of Char;
        Classe:array[0..250]of Char;
    begin
      if(IsWindow(aWnd))then
      begin
        GetWindowText(aWnd,Texte,SizeOf(Texte)); // récupération du texte de la fenêtre
        GetClassName(aWnd,Classe,SizeOf(Classe)); // récupération de la classe
        Form1.Memo1.lines.add('classe :'+Classe+'      Texte: '+Texte+'    Handle: '+IntToStr(aWnd)
        +' Exécutable : '+GetProcessNameFromHandle(aWnd))
      end;
      Result := TRUE;
    end;
     
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      EnumWindows(@EnumWindowsCallback, 0);
    end;
     
    end.
    Je ne sais pas si c'est correct mais j'obtiens la liste des fenêtres
    Petit hic, pour Mozilla, y en a 3/4 donc bon, faut que je teste voir ce que ça donne

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/07/2014, 08h39
  2. [Spip] afficher les articles d'une sous sous rubrique en passant par les rubriques parents
    Par Abou Zar dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 0
    Dernier message: 06/08/2012, 17h50
  3. [AC-2007] Filtrer les données d'une requête en passant par VBA
    Par Oliv'83 dans le forum VBA Access
    Réponses: 6
    Dernier message: 27/04/2011, 12h07
  4. Réponses: 0
    Dernier message: 23/06/2010, 10h35
  5. Copies de flots en passant par les itérateurs
    Par Christophe Brun dans le forum C++
    Réponses: 7
    Dernier message: 02/07/2003, 11h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo