Entwickler-Ecke

Windows API - Wie kann ich alle sichtbaren Fenster anzeigen lassen


stefanstp - Di 17.12.02 19:56
Titel: Wie kann ich alle sichtbaren Fenster anzeigen lassen
Ich möchte ganz gerne alle sichtbaren Fenster in einer Listbox anzeigen lassen, damit ich z.B. einen PopUpkiller erstellen könnte. Mit diesem Beispiel geht es nicht, weil er auch nicht sichtbare Fenster anzeigt:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function EnumWinProc(Wnd: hWnd; Frm: TForm1): Boolean; Export; StdCall;
var
  WinText: Array[0..255] of Char;
begin
  GetWindowText(Wnd, WinText, 255); 
  Result := True;
  if (StrPas(WinText) <> '') then
  Frm.ListBox1.Items.Add(IntToStr(Wnd) + ': ' + StrPas(WinText));
end; 


procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Items.Clear;
  EnumWindows(@EnumWinProc, LongInt(self));

Wer kann helfen? Besten Dank im voraus!

STEFAN

(18.12. 14:11 Tino) Code-Tags hinzugefügt.


Moritz M. - Di 17.12.02 20:21

Hi

Hab mal auf swissdelphicenter nachgeschaut und das gefunden:
http://swissdelphicenter.ch/de/showcode.php?id=410


Rooof - Mi 18.12.02 11:46

Hallo Stefan

Ich hatte bis vor etwa 10min das selbe Problem, nämlich dass immer alle Fenster angezeigt worden sind in der ListBox. Hier nun das korrekte Beispiel:


Quelltext
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:
function EnumWinProc(Wnd: hWnd; Frm: TForm1): Boolean; Export; StdCall;
var 
WinText: Array[0..255] of Char;
pRect:TRect;
begin
  GetWindowText(Wnd, WinText, 255);
  GetWindowRect(Wnd, pRect);
  Result := True;
  if (StrPas(WinText) <> '') then
  begin
    if GetWindow(Wnd, GW_CHILD) <> 0 then
    begin
      if pRect.Left > 0 then
      begin
        if (GetWindowLong(Wnd, GWL_STYLE) and WS_VISIBLE) <> 0 then
        begin
          Frm.ListBox1.Items.Add(IntToStr(Wnd) + ': ' + StrPas(WinText));
        end;
      end;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.Clear;
EnumWindows(@EnumWinProc, LongInt(self));

end;


Der Vorteil von diesem Code ist auch, dass die Maximierten Fenster auch gleich ausgeschaltet werden, das heisst, nicht angezeigt werden.

Der Entscheidenede Code ist aber der:

Quelltext
1:
if (GetWindowLong(Wnd, GWL_STYLE) and WS_VISIBLE) <> 0 then                    


Man, bis ich das rausgefunden hatte....hat mich eine schöne Zeit gekostet :wink:

Ich hoffe, dir ist damit auch geholfen....

Greets Rooof


stefanstp - Mi 18.12.02 12:06
Titel: Besten dank...werde ich gleich heute Abend ausprobieren!
...werde morgen Bescheid sagen, ob Dein Code funktioniert! Besten dank im voraus!

STEFAN


Delete - Mi 18.12.02 15:08

Ich schmeiße mal so ein paar Vereinfachungen in die Diskussion: IsWindow und IsWindowVisible.

Desweiteren würde ich es so machen:

Quelltext
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:
type
PMyEnumParam = ^TMyEnumParam;
TMyEnumParam = record
  lb: TListbox;
end;

function GetWindows(const hWnd : Longword; Param: PMyEnumParam): LongBool; stdcall;
var
  Len : Longint;
  S   : String;
begin
  Result := True;
  if not ( IsWindow(hWnd) and IsWindowVisible(hWnd) ) then Exit;
  Len := SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0);
  if Len > 0 then
  begin
    SetLength(S, Len);
    SendMessage(hWnd, WM_GETTEXT, Len + 1, Longint(Pchar(S)));
    Param.lb.Items.Add(s);
  end;
  // mit Result = False kann die Callbackfunktion vorzeitig verlassen werden
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Param: TMyEnumParam;
begin
  Param.lb := Listbox1;
  EnumWindows(@GetWindows, LPARAM(@Param));
end;


stefanstp - Do 19.12.02 09:46
Titel: Danke...an allen!
..hat sehr gut geklappt!

Schönes Wochenende und schöne Weihnachten wünsche ich!

STEFAN


Moritz M. - Do 19.12.02 13:23

Die ebenfalls!
Und nen guten Rutsch!! :beer: