Создайте форму и разместите на ней два компонента ListBox.
Скопируйте код, показанный ниже.
Запустите SysEdit.
Запустите форму Delphi. Первый ListBox должен содержать список всех
запущенных приложений. Дважды щелкните на SysEdit и нижний ListBox покажет
дочернее MDI-окно программы SysEdit.
unit Wintask1;
interfaceuses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
ListBox2: TListBox;
procedure FormCreate(Sender: TObject);
procedure ListBox1DblClick(Sender: TObject);
privatefunction enumListOfTasks(hWindow: hWnd): Bool; export;
function enumListOfChildTasks(hWindow: hWnd): Bool; export;
end;
THoldhWnd = class(TObject)
privatepublic
hWindow: hWnd;
end;
var
Form1: TForm1;
implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
begin
enumWindows(@TForm1.EnumListOfTasks, Longint(Self));
if (ListBox1.Items.Count > 0) then
ListBox1.ItemIndex := 0;
end;
function TForm1.enumListOfTasks(hWindow: hWnd): Bool;
var
HoldString: PChar;
WindowStyle: Longint;
IsAChild: Word;
HoldhWnd: THoldhWnd;
begin
GetMem(HoldString, 256);
HoldhWnd := THoldhWnd.Create;
HoldhWnd.hWindow := hWindow;
WindowStyle := GetWindowLong(hWindow, GWL_STYLE);
WindowStyle := WindowStyle and Longint(WS_VISIBLE);
IsAChild := GetWindowWord(hWindow, GWW_HWNDPARENT);
{Добавляем строку с текстом задачи или именем класса и дескриптор в ListBox1.Items }if (GetWindowText(hWindow, HoldString, 255) > 0) and
(WindowStyle > 0) and (IsAChild = Word(nil)) then
ListBox1.Items.AddObject(StrPas(HoldString), TObject(HoldhWnd))
elseif (GetClassName(hWindow, HoldString, 255) > 0) and
(WindowStyle > 0) and (IsAChild = Word(nil)) then
ListBox1.Items.AddObject(Concat('<', StrPas(HoldString), '>'),
TObject(HoldhWnd));
FreeMem(HoldString, 256);
HoldhWnd := nil;
Result := TRUE;
end;
function TForm1.enumListOfChildTasks(hWindow: hWnd): Bool;
var
HoldString: PChar;
WindowStyle: Longint;
IsAChild: Word;
HoldhWnd: THoldhWnd;
begin
GetMem(HoldString, 256);
HoldhWnd := THoldhWnd.Create;
HoldhWnd.hWindow := hWindow;
WindowStyle := GetWindowLong(hWindow, GWL_STYLE);
WindowStyle := WindowStyle and Longint(WS_VISIBLE);
IsAChild := GetWindowWord(hWindow, GWW_HWNDPARENT);
{Добавляем строку с текстом задачи или именем класса и дескриптор в ListBox1.Items }if (GetWindowText(hWindow, HoldString, 255) > 0) and
(WindowStyle > 0) and (IsAChild <> Word(nil)) then
ListBox2.Items.AddObject(StrPas(HoldString), TObject(HoldhWnd))
elseif (GetClassName(hWindow, HoldString, 255) > 0) and
(WindowStyle > 0) and (IsAChild = Word(nil)) then
ListBox2.Items.AddObject(Concat('<', StrPas(HoldString), '>'),
TObject(HoldhWnd));
FreeMem(HoldString, 256);
HoldhWnd := nil;
Result := TRUE;
end;
procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
enumChildWindows(THoldhWnd(ListBox1.Items.Objects[ListBox1.ItemIndex]).hWindow,
@TForm1.enumListOfChildTasks, Longint(Self));
ListBox2.RePaint;
end;
end.
Пример использования функции EnumWindows в Delphi для списка всех запущенных приложений и их дочерних окон.
Вот разбивка того, что код делает:
Определен класс TForm1, который включает два компонента TListBox (ListBox1 и ListBox2) и процедуру FormCreate.
В процедуре FormCreate вызывается функция EnumWindows с двумя параметрами: callback-функцией (@TForm1.EnumerateTasks) и объектом формы (Longint(Self)).
Функция EnumerateTasks вызывается для каждого окна в системе. Она проверяет, является ли окно видимым (GetWindowLong(hWindow, GWL_STYLE) and WS_VISIBLE) и не является ли дочерним окном (GetWindowWord(hWindow, GWW_HWNDFPARENT) = 0). Если эти условия выполняются, она добавляет заголовок или имя класса окна в ListBox1. Items вместе с ссылкой на объект THoldhWnd.
Функция EnumChildWindows вызывается в процедуре ListBox1DblClick, когда пользователь дважды кликает по элементу в ListBox1. Эта функция перечисляет все дочерние окна выбранного окна и добавляет их в ListBox2. Items.
Класс THoldhWnd - это простой оберток вокруг HWND (идентификатор окна), позволяющий хранить дополнительную информацию о каждом окне.
Вот некоторые предложения по улучшению:
Вместо использования глобальных переменных, рассмотрите использование переменных экземпляра в классе формы.
Вы можете использовать тип TList вместо создания собственного класса THoldhWnd.
Рассмотрите использование более robust механизма обработки ошибок. Например, вы можете проверять возвращаемое значение функций GetWindowLong и GetWindowText, чтобы обрабатывать ошибки.
Вам может потребоваться добавление логике фильтрации для отображения только релевантных окон в списке.
Вот пример альтернативного решения: вы можете использовать функцию ProcessList из единицы SysUtils, чтобы получить список всех запущенных процессов. Это может быть полезно, если вам нужно отобразить информацию о процесс-уровневых задачах. Однако это подход может не предоставлять столько же деталей, как использование EnumWindows для перечисления окон.
Вот пример использования ProcessList:
procedureTForm1.FormCreate(Sender:TObject);beginProcessList:=TStringList.Create;tryProcessList.LoadFromFile('C:\Windows\System32\Tasklist.exe');// Process list loaded, now iterate over it and add items to ListBox1finallyProcessList.Free;end;end;
В этом коде загружается список процессов из файла Tasklist.exe и хранится в объекте TStringList. Затем вы можете перечислять список и добавлять элементы в ListBox1. Однако это подход может не предоставлять столько же деталей о каждом процессе, как использование EnumWindows для перечисления окон.
Пример EnumWindows - это статья, которая демонстрирует использование функции EnumWindows для enumeration всех запущенных приложений и их дочерних окон в системе Windows.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.