Пример EnumWindows

Создайте форму и разместите на ней два компонента ListBox.
Скопируйте код, показанный ниже.
Запустите SysEdit.
Запустите форму Delphi. Первый ListBox должен содержать список всех запущенных приложений. Дважды щелкните на SysEdit и нижний ListBox покажет дочернее MDI-окно программы SysEdit.
Paul Powers (Borland)

unit Wintask1;



interface



uses

 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);

 private

  function enumListOfTasks(hWindow: hWnd): Bool; export;

  function enumListOfChildTasks(hWindow: hWnd): Bool; export;

 end;



 THoldhWnd = class(TObject)

 private

 public

  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))

 else if (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))

 else if (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.

Дополнение
В Kuliba1000.chm Win32 API/Разное/ есть принципиальная ошибка в коде:
ЛЮБАЯ callback ( обратного вызова ) функция в Delphi должна сопровождаться директивой stdcall.
Предоставленный пример просто не работает.
Определение класса формы должно выглядеть как-то так:
type

 TForm1 = class(TForm)

  ListBox1: TListBox;

  ListBox2: TListBox;

  procedure FormCreate(Sender: TObject);

  procedure ListBox1DblClick(Sender: TObject);

 private

  function enumListOfTasks(hWindow: hWnd): Bool; stdcall;

  function enumListOfChildTasks(hWindow: hWnd): Bool; stdcall;

 end;

Директивы export (это написано в Help'е) просто не работают (игнорируются) под Win 32 :(
С наилучшими пожеданиями
Андрей Бреслав
Взято из Советов по Delphi от Валентина Озерова
Сборник Kuliba

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...