Как получить список всех окон
Программа Enumeration работает с функциями API. На форму нужно поместить компонент дерева TTreeView (tv1) и кнопку TButton (btnEnum). В обработчике события нажатия на кнопку запишите:
procedure TForm1.btnEnum(Sender: TObject); begin Screen.Cursor:= crHourGlass; try tv1.Items.Clear; EnumWindows(@EnumWindowsProc,0); finally Screen.Cursor:= crDefault; end; end;
Здесь сначала мы очищаем TTreeView (tv1) и вызываем функцию EnumWindows, передавая ей функцию обратного вызова EnumWindowsProc, которая и будет делать основную работу по поиску окон и заполнение дерева.
Для начала функцию обратного вызова EnumWindowsProc нужно объявить:
{ ... } var Form1: TForm1; { ... } function EnumWindowsProc(Wnd: HWND; ParentNode: TTreeNode): Bool; stdcall;
Функция обратного вызова EnumWindowsProc:
function EnumWindowsProc(Wnd: HWND; ParentNode: TTreeNode): Bool; stdcall; const ClassNameLen = 512; // т.к. мы не знаем длину имени класса заранее, выделим достаточно места var Text: string; // Заголовок окна TextLen: integer; // Длина заголовка ClassName: array[0..ClassNameLen-1] of Char; // буфер для имени класса Node: TTreeNode; NodeName: string; begin Result:= true; // Будем искать только прямых потомков, остальные игнорируем if Assigned(ParentNode) and (GetParent(Wnd) <> HWND(ParentNode.Data)) then Exit; // Получаем длину заголовка окна TextLen:= SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0); // Устанавливаем длину строковой переменной SetLength(Text, TextLen); if TextLen > 0 then SendMessage(Wnd, WM_GETTEXT, TextLen+1, LParam(Text)); // Слишком длинные строки обрезаем if TextLen > 100 then Text:= Copy(Text, 1, 100) + ' ' ; GetClassName(Wnd, ClassName, ClassNameLen); ClassName[ClassNameLen-1]:= #0; if Text = '' then NodeName:= 'Без названия (' + ClassName + ')' else NodeName:= Text + ' (' + ClassName + ') '; Node:= Form1.tv1.Items.AddChild(ParentNode, NodeName); Node.Data:= Pointer(Wnd); EnumChildWindows(Wnd, @EnumWindowsProc, LParam(Node)); end;
Комментарии