Link to home
Start Free TrialLog in
Avatar of din345
din345

asked on

get all opened internet explorer windows

I want to get all opened internet explorer windows and add the window's caption to a ListBox.
i don't want the program to unselect the selected item in the listbox when it gets updated by the timer, so it does a for-loop and checks if the content in the stringlist (IEWndsList) has been changed, if so, then it puts the content in the listbox.

i use the following code:
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    ListBox1: TListBox;
    Closewindow1: TMenuItem;
    Timer1: TTimer;
    procedure Closewindow1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  IEWndsList: TStringList;
  index: integer;

implementation

{$R *.dfm}

function EnumIEWndsProc(hWnd, lParam: Integer): Boolean; stdcall;
var Cap: PChar;
    Len: Integer;
    cn: array[0..7] of Char;
begin
 Result := True;
 GetClassName(hWnd, cn, 8);
 if cn = 'IEFrame' then begin
   Len := GetWindowTextLength(hWnd) + 1;
   GetMem(Cap, Len);
   GetWindowText(hWnd, Cap, Len);
   IEWndsList.Add(Cap);
   FreeMem(Cap);
 end;
end;

procedure SetHorizontalScroll(alb: TListBox);
var i, len, lbsw: integer;
begin
lbsw := 0;
 with alb do begin
  for i := 0 to Items.Count - 1 do begin
   len := Canvas.TextWidth(Items[i]);
   if len > lbsw then lbsw := len;
  end;
  Perform(LB_SETHORIZONTALEXTENT, lbsw + 7, 0);
 end;
end;

procedure TForm1.Closewindow1Click(Sender: TObject);
begin
 if ListBox1.ItemIndex <> -1 then SendMessage(FindWindow(nil, PChar(ListBox1.Items.Strings[ListBox1.ItemIndex])), WM_SYSCOMMAND, SC_CLOSE, 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var a, b: integer;
    BreakIt: Boolean;
begin
 // timer interval = 1
 BreakIt := False;
 index := listbox1.ItemIndex;
 IEWndsList.Clear;
 EnumWindows(@EnumIEWndsProc, 0);
 for a := 0 to IEWndsList.Count - 1 do begin
    for b := 0 to ListBox1.Items.Count - 1 do begin
       if IEWndsList[a] <> ListBox1.Items[b] then begin
         ListBox1.Items.Assign(IEWndsList);
         SetHorizontalScroll(ListBox1);
         listbox1.ItemIndex := index;
         BreakIt := True;
         Break;
       end;
    end;
    if BreakIt then Break;
 end;
 // now you wonder why i wrote "if IEWndsList[a]..."? i wrote it
 // because when i select an item in the listbox and it gets
 // updated (by the timer, every 1 ms) and when i right-click
 // on it and want to close the window, it gets unselected.
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 IEWndsList := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 IEWndsList.Free;
end;

end.
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

Use IShellWindows and get the document title, that is what IE places in the Caption:


uses  .., SHDocVw, mshtml
procedure TForm1.Button1Click(Sender: TObject);
var
  x : Integer;
  sw: IShellWindows;
  wb: IWebbrowser2;
  Doc: IHTMLDocument2;
begin
  sw := CoShellWindows.Create;
  for x := 0 to sw.count do
  begin
    WB := Sw.Item(x) as IWebbrowser2;
    if wb<>nil then
    begin
      doc := WB.Document as IHTMLDocument2;
      ListBox1.Items.Add(Doc.Title);
    end;
  end;
end;
Avatar of geobul
geobul

What is the question actually?
Avatar of din345

ASKER

EddieShipman: i don't have SHDocVw and mshtml (i have delphi 7 personal...)

geobul: i want to create a program like task manager, but it should only add all internet explorer windows captions to a listbox. how can i do that?
The import the Microsoft HTML and/or Internet Explorer libraries.
If you have TWebBrowser, you have ShDocVW!!!
try this

  var
      currentHandle,NextHandle: Hwnd;
      Title : array[0..255] of char;

  currentHandle := FindWindow('IEFrame',nil);
  ListBox1.Items.Add(GetWindowText(currentHandle,Title,255));
  NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);

I would make an working example if is not sufficent for you ;-)
Here is a solution :

just put one ListBox (listBox1) and one Button (button1)

-----------------------------------------------------------------------------------------

function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
var
  Title, ClassName: array[0..255] of char;
begin
  Result := True;
  GetWindowText(wHandle, Title, 255);
  GetClassName(wHandle, ClassName, 255);
  if IsWindowVisible(wHandle) and (ClassName='IEFrame') then
     lb.Items.Add(string(Title) + '-' + string(ClassName));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumWindowsProc, Integer(Listbox1));
end;
-----------------------------------------------------------------------------------------

Avatar of din345

ASKER

i have solved the problem:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    ListBox1: TListBox;
    Closewindow1: TMenuItem;
    Timer1: TTimer;
    procedure Closewindow1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  IEWndsList: TStringList;
  index, scrollPos: integer;

implementation

{$R *.dfm}

function EnumIEWndsProc(hWnd, lParam: Integer): Boolean; stdcall;
var Cap: PChar;
    Len: Integer;
    cn: array[0..7] of Char;
begin
 Result := True;
 GetClassName(hWnd, cn, 8);
 if cn = 'IEFrame' then begin
   Len := GetWindowTextLength(hWnd) + 1;
   GetMem(Cap, Len);
   GetWindowText(hWnd, Cap, Len);
   IEWndsList.Add(Cap);
   FreeMem(Cap);
 end;
end;

procedure SetHorizontalScroll(alb: TListBox);
var i, len, lbsw: integer;
begin
lbsw := 0;
 with alb do begin
  for i := 0 to Items.Count - 1 do begin
   len := Canvas.TextWidth(Items[i]);
   if len > lbsw then lbsw := len;
  end;
  Perform(LB_SETHORIZONTALEXTENT, lbsw + 7, 0);
 end;
end;

procedure TForm1.Closewindow1Click(Sender: TObject);
begin
 if ListBox1.ItemIndex <> - 1 then SendMessage(FindWindow(nil, PChar(ListBox1.Items.Strings[ListBox1.ItemIndex])), WM_SYSCOMMAND, SC_CLOSE, 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var a, b: integer;
begin
 // timer interval = 1
 index := listbox1.ItemIndex;
 IEWndsList.Clear;
 EnumWindows(@EnumIEWndsProc, 0);
 for a := 0 to IEWndsList.Count - 1 do begin
    if ListBox1.Items.IndexOf(IEWndsList[a]) = - 1 then begin
      ListBox1.Items.Assign(IEWndsList);
      SetHorizontalScroll(ListBox1);
      listbox1.ItemIndex := index;
      Break;
    end;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 IEWndsList := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 IEWndsList.Free;
end;

end.

but i got a new problem now.. when i rightclick on an item and click 'Close window' on the popupmenu, the item is still in the listbox, how can i delete it? (shouldn't EnumWindows() delete it...??)
maybe you should use

 SendMessage(MyHandle, WM_CLOSE, 0, 0);

I try it now ;-)
ASKER CERTIFIED SOLUTION
Avatar of krypto2000
krypto2000

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
glad to help you ;-)
That has to go through ALL Windows whereby the ShellWindows solution only has to go
through the IE Windows.

Too bad the OP didn't see that or know how to import MSHTML/IE Type Libs...