Link to home
Start Free TrialLog in
Avatar of neshkov
neshkov

asked on

Browse for ALL instances of an application

Hi all,
I want to know how can browse and find all instances of an application. For example: I want to find and maximize ALL windows that contains the string 'MyAppWindow'. Please include some code examples.

Thanks for your help in advance!
Best Regards
Avatar of kretzschmar
kretzschmar
Flag of Germany image

look at enumwindows in winAPI
Avatar of neshkov
neshkov

ASKER

Example please!
ASKER CERTIFIED SOLUTION
Avatar of Igor UL7AAjr
Igor UL7AAjr
Flag of Kazakhstan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
found an old sample in my paq (from january 1999)

--- paste begin
here is a little unit which collects windows and childwindows (handle, Caption ControlClass) and displayed
it in a treeview, not ready, not perfect, of course but it shows a way

unit fw_tree_u;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, ExtCtrls, Grids, ComCtrls;

type
 TForm1 = class(TForm)
   Panel1: TPanel;
   Button1: TButton;
   TV1: TTreeView;
   Splitter1: TSplitter;
   Panel2: TPanel;
   EClass: TEdit;
   EText: TEdit;
   EHandle: TEdit;
   Label1: TLabel;
   Label2: TLabel;
   Label3: TLabel;
   Button2: TButton;
   Button3: TButton;
   procedure Button1Click(Sender: TObject);
   procedure TV1Click(Sender: TObject);
   procedure TV1Change(Sender: TObject; Node: TTreeNode);
   procedure Button2Click(Sender: TObject);
 private
   { Private-Deklarationen }
 public
   { Public-Deklarationen }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

type
TTextBuf = array[0..100] of Char;
TTNData = Record
            ClassName : String[100];
            Caption   : String[100];
            Handle    : LongInt;
          end;

var
TNDPtr : ^TTNData;
TextBuf: TTextBuf;
TextBufPtr: PChar = TextBuf;
ActNode : TTreeNode;

Function MyClassName(CHandle : THandle) : String;
begin
 GetClassName(CHandle,TextBufPtr,100);
 Result := strpas(TextBufPtr);
end;

Function ControlCaption(CHandle : THandle) : String;
begin
 Getwindowtext(CHandle,TextBufPtr,100);
 Result := strpas(TextBufPtr);
end;

Procedure FindChilds(Depth : Integer; ParentW: THandle; Node : TTreeNode);
var
 ch1: THandle;
 s : String;
 i : Integer;
 TActNode : TTreeNode;
begin
 s := '';
 for i := 0 to depth do s := s + ':-';
 ch1 := GetWindow(ParentW, GW_Child);
 while not(ch1=0) do
 begin
   New(TNDPTr);
   TNDPtr^.ClassName := MyClassName(ch1);
   TNDPtr^.Caption := ControlCaption(ch1);
   TNDPtr^.Handle := ch1;
   TActNode := Form1.TV1.Items.AddChildObject(Node,TNDPtr^.ClassName,TNDPtr);
   ch1 := GetNextWindow(ch1, GW_HWNDNEXT);
 end;
 ch1 := GetWindow(ParentW, GW_Child);
 while not(ch1=0) do
 begin
   if GetWindow(ch1, GW_Child)<>0 then FindChilds(depth + 1,ch1,TactNode);
   ch1 := GetNextWindow(ch1, GW_HWNDNEXT);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 SHandle,
 FHandle : THandle;
begin
 SHandle := GetActiveWindow;
 while (SHandle <> 0) do
 begin
   SHandle :=  GetWindow(SHandle,GW_HWNDNEXT);  {Looking Foward the Z-Order}
   if SHandle <> 0 then
   begin
     New(TNDPTr);
     TNDPtr^.ClassName := MyClassName(SHandle);
     TNDPtr^.Caption := ControlCaption(SHandle);
     TNDPtr^.Handle := SHandle;
     ActNode := TV1.Items.AddChildObject(TV1.TopItem,TNDPtr^.ClassName,TNDPtr);
     FindChilds(0,SHandle,ActNode);
   end;
 end;
 SHandle := GetActiveWindow;
 while (SHandle <> 0) do
 begin
   SHandle := GetWindow(SHandle,GW_HWNDPREV); {Looking Backward the Z-Order}
   if SHandle <> 0 then
   begin
     New(TNDPTr);
     TNDPtr^.ClassName := MyClassName(SHandle);
     TNDPtr^.Caption := ControlCaption(SHandle);
     TNDPtr^.Handle := SHandle;
     ActNode := TV1.Items.AddChildObject(TV1.TopItem,TNDPtr^.ClassName,TNDPtr);
     FindChilds(0,SHandle,ActNode);
   end;
 end;
end;


procedure TForm1.TV1Click(Sender: TObject);
begin
 If TV1.Selected = TV1.TopItem then
 begin
   EClass.Text := '';
   EText.Text := '';
   EHandle.Text := '0';
 end
 else
 begin
   if TV1.Selected <> nil then
   begin
     TNDPtr := TV1.Selected.Data;
     EClass.Text := TNDPtr^.ClassName;
     EText.Text := TNDPtr^.Caption;
     EHandle.Text := inttostr(TNDPtr^.Handle);
   end
   else
   begin
     EClass.Text := '';
     EText.Text := '';
     EHandle.Text := '0';
   end;
 end;
end;

procedure TForm1.TV1Change(Sender: TObject; Node: TTreeNode);
begin
 TV1Click(self);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 showwindow(strtoint(ehandle.text),SW_SHOW);
end;

end.


meikl

--- paste end

matches not your needs, but may give a suggestion how to do it

meikl ;-)

hi, igor :-)

meikl ;-)
meikl :-)
hmm,
my sample doesn't use enumwindows,
it uses another alternative way,
maybe i should dig again in my paq

meikl ;-)
meikl,
yes, it's look like big enought :-)
-----
Igor.
hopefully madshi isn't angry about me
its unit at

www.madshi.net/enumStuff.zip

makes all easier

meikl ;-)
Why should I be angry? It's always nice to be referenced by other experts...   :-)

Igor, your NextWindow function needs to have a "bool" result, which has to be set to true. Otherwise the enumeration may stop, depending on random.

meikl, the documentation about EnumWindows sais this: "This function is more reliable than calling the GetWindow function in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.". So we should really better use EnumWindows.

Regards, Madshi.
Avatar of neshkov

ASKER

Thank you Madshi!
OK, Igor, can you please rewrite your example?
:-) i know, madshi, just got the wrong sample from my paq
:-)
Avatar of neshkov

ASKER

Thank you gays!
Ok,
here is it.

function NextWindow(H,V:Integer): Boolean; stdcall;
var
 C: array[0..255] of char;
begin
 GetClassName(H, C, 255);

 if C = 'TForm1' then
   ShowWindow(H, SW_MINIMIZE);
 EnumChildWindows(H, @NextWindow, V);
 Result := true;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
 EnumWindows(@NextWindow, 0);
end;


Thanx for the points.
Ehmm... "Boolean" is 1 byte long. In fact it has to be "BOOL", which is 4 byte long. Well, it doesn't really matter much, because the result is returned in the register EAX, which is already 4 bytes long, but, hey, I'm a perfectionist...   :-)

Regards, Madshi.
Avatar of neshkov

ASKER

Hey Madshi, are you a german? ;)
...Best Regards