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?