Wie bekomme ich Zugriff auf alle geöffneten Fenster?
Den Anzeige-Zustand und die Position eines Fensters ermittelt man mit der API-Funktion GetWindowPlacement. Die folgende Funktion GetWindowState gibt den Anzeigezustand des Fensters mit dem Handle Wnd zurück:
function GetWindowState(Wnd : HWnd) : integer;
var WPlacement : PWINDOWPLACEMENT;
begin
GetMem(WPlacement,SizeOf(TWINDOWPLACEMENT));
WPlacement^.Length := SizeOf(TWINDOWPLACEMENT);
if GetWindowPlacement(Wnd,WPlacement) then
Result := WPlacement^.showCmd
else
Result := -1;
FreeMem(WPlacement);
end;
mögliche Rückgabewerte: SW_HIDE, SW_MINIMIZE, SW_RESTORE, SW_SHOW, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_SHOWNOACTIVATE oder SW_SHOWNORMAL (siehe auch in der API-Hilfe zur Funktion GetWindowPlacement).
Das nachfolgende Unit demonstriert die folgenden API-Funktionen:
EnumWindows,
GetWindowText,
GetClassName,
IsWindowVisible,
GetWindowThreadProcessID und
GetProcessVersion.
Mit Hilfe dieser Funktionen wird eine Liste aller aktuell geöffneten Fenster und deren
Handles, Prozess-IDs, Klassen, Titel, etc.
erstellt. Auch die Funktion zur Ermittlung des mit dem Fenster verbundenen EXE-Namens wird
demonstriert. Die API-Funktionen die Process32First und Process32Next sind nur unter W95
definiert, daher funktioniert die Unit so nicht unter Windows NT.
Bitte bei Benutzung/Weitergabe die Autoren angeben.
{ Unit to demonstrate the usage of EnumWindows and some according API-functions
Christoph Handel, Simon Reinhardt and Christian Kästner in October 1998
Uses Messages to transport the Wnd-Handle.
This way you do not need to directly use the Form variable }
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls,
ComCtrls, ExtCtrls, TLHelp32, ShellApi;
type
TMainForm = class(TForm)
PanelTop: TPanel;
btnEnumerate: TButton;
PanelMain: TPanel;
ListView: TListView;
LblAnzahl: TLabel;
procedure btnEnumerateClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ListViewColumnClick(Sender: TObject; Column: TListColumn);
private
{ Private-Deklarationen }
WM_ENUMERATE_ID: integer;
public
{ Public-Deklarationen }
procedure WriteText(Wnd: HWnd);
procedure WndProc(var Message: TMessage); override;
end;
var
MainForm : TMainForm;
SortColumn : integer;
function RegisterMessage: integer;
// get a messageID from Windows
function EnumWinProc(Wnd: HWnd; param: lParam): boolean; stdcall;
// this is the callbackfunction. Don't miss stdcall
// can't be part of the form.
implementation
{$R *.DFM}
function RegisterMessage: integer;
begin
Result := RegisterWindowMessage('Enumerate this Window');
end;
function EnumWinProc(Wnd: HWnd; param: lParam): boolean; stdcall;
var iMsgID: integer;
begin
iMsgID := RegisterMessage;
SendMessage(param, iMsgID, 0, Wnd);
// give data to main form
Result := true;
end;
procedure TMainForm.WndProc(var Message: TMessage);
begin
if Message.Msg=WM_ENUMERATE_ID then
// oh! Enumerate Window found a window, lets do something
WriteText(Message.lParam)
else
inherited WndProc(Message);
end;
{These procedures by Simon Reinhardt:}
//Sort the listitems alphabetically
function MySortProc(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall;
var T1,T2 : string;
begin
case SortColumn of
0 : begin
T1 := Item1.Caption;
T2 := Item2.Caption;
end
else begin
T1 := Item1.SubItems[SortColumn-1];
T2 := Item2.SubItems[SortColumn-1];
end
end;
Result := lstrcmp(PChar(T1),PChar(T2));
end;
//fill in the listview with all the information
procedure TMainForm.WriteText(Wnd: HWnd);
var pcWinText : PChar;
NewItem : TListItem;
aProcessEntry32 : TProcessEntry32;
aSnapshotHandle : THandle;
WinVersion : DWord;
ProcessID : longint;
ContinueLoop : boolean;
begin
NewItem := ListView.Items.Add;
{Is Window Visible?}
NewItem.Checked := IsWindowVisible(wnd);
{WindowCaption}
pcWinText := StrAlloc(102);
GetWindowText(Wnd, pcWinText, 100);
NewItem.Caption := StrPas(pcWinText);
StrDispose(pcWinText);
{WindowClassName}
pcWinText := StrAlloc(102);
GetClassName(Wnd, pcWinText, 100);
NewItem.SubItems.Add(StrPas(pcWinText));
StrDispose(pcWinText);
{WindowHandle}
NewItem.SubItems.Add(IntToHex(wnd, 8));
{WindowThreadProcessID}
GetWindowThreadProcessID(wnd,@ProcessID);
NewItem.SubItems.Add(IntToHex(ProcessID, 8));
{WindowsVersion}
WinVersion := GetProcessVersion(ProcessID);
NewItem.SubItems.Add(IntToStr(WinVersion shr 16)+'.'+IntToStr(WinVersion mod $1000));
{CommandLine}
{According to Christian Kästner:}
aSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
aProcessEntry32.dwSize := Sizeof(aProcessEntry32);
ContinueLoop := Process32First(aSnapshotHandle, aProcessEntry32);
while integer(ContinueLoop)<>0 do begin
if aProcessEntry32.th32ProcessID = ProcessID then
NewItem.SubItems.Add(ExtractFileName(aProcessEntry32.szExeFile));
ContinueLoop := Process32Next(aSnapshotHandle,aProcessEntry32);
end;
CloseHandle(aSnapshotHandle);
{end of Chrstian's stuff}
end;
//sort the listview on columnclick
procedure TMainForm.ListViewColumnClick(Sender: TObject; Column: TListColumn);
begin
SortColumn := Column.Index;
ListView.CustomSort(@MySortProc, 0);
end;
{end of Simons part}
procedure TMainForm.btnEnumerateClick(Sender: TObject);
begin
ListView.Items.Clear;
EnumWindows(@EnumWinProc, self.Handle);
// start EnumerateWindows, send the Handle of the Form
// so function nows where to send the info
LblAnzahl.Caption := 'Anzahl : '+IntToStr(ListView.Items.Count);
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
WM_ENUMERATE_ID:= RegisterMessage;
// get our msgID
end;
end.
| Delphi 1 | Delphi 2 | Delphi 3 | Delphi 4 |
| nicht getestet | Version nicht betroffen | getestet |
siehe auch:
Wie kann ich die Programmdatei (*.exe) einer Anwendung über deren
Fensterhandle ermittteln?