Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Hello, World!
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  01:11[Войти] | [Зарегистрироваться]

Обобщающие примеры работы с WinAPI. Пример №5 — работа с процессами системы.

Антон Григорьев
дата публикации 14-10-2005 03:47

Обобщающие примеры работы с WinAPI. Пример №5 — работа с процессами системы.

Более полный вариант этой статьи вошёл в книгу "О чём не пишут в книгах по Delphi"

Данный пример показывает, как можно получить список процессов, запущенных в системе, список модулей и окон, принадлежащих каждому из процессов, и информацию о каждом из окон.

Получение списка процессов

Исторически сложилось, что существует два способа получить список процессов: с помощью функций Tool Help и с помощью функций PSAPI. Эти две группы функций использовались в разных линиях Windows: функции Tool Help появились в Windows 95, функции PSAPI - в Windows NT 4. Windows 2000/XP также поддерживают функции Tool Help, в то время как Windows 98/ME не поддерживают PSAPI. Поэтому мы будем использовать функции Tool Help - это даст нашему примеру возможность работать во всех версиях Windows, кроме NT 4 (впрочем, в Windows 95 пример тоже не будет работать, но по другой причине: из-за функций GetWindowInfo и RealGetWindowClass, отсутствующих в этой версии). Функции Tool Help объявлены в модуле TlHelp32.

Для получения списка процессов необходимо сделать снимок состояния системы с помощью функции CreateToolhelp32Snapshot. Эта функция создаёт специальный объект, который может хранить информацию о процессах, модулях, нитях и кучах, созданных в системе. Этот объект называется снимком потому, что информация, хранящаяся в нём, актуальна на момент вызова функции CreateToolhelp32Snapshot; дальнейшие изменения списка процессов, модулей и т.п. не приводят к изменению снимка. Доступ к снимку, как и к большинству объектов системы, осуществляется через его дескриптор.

Навигация по списку процессов, сохранённых в снимке, осуществляется с помощью функций Process32First и Process32Next. Они позволяют получить ряд параметров процесса, главный среди которых - идентификатор процесса (Process Identifier; PID). Это - уникальный идентификатор процесса, с помощью которого можно отличать один процесс от другого.

Примечание: не следует путать идентификатор процесса и дескриптор объекта процесса, который используется, например, в функции SetPriorityClass. Объект процесса - это специальный объект, связанный с процессом, но не тождественный ему. В частности, объект процесса может продолжать существовать уже после того, как сам процесс завершит работу - это позволяет, например, корректно синхронизироваться с уже завершённым процессом при помощи функции WaitForSingleObject. Через объект процесса можно управлять многими свойствами процесса. Поучить дескриптор объекта процесса по идентификатору процесса можно с помощью функции OpenProcess.

Для получения списка модулей данного процесса также используется снимок. Навигация по снимку модулей осуществляется с помощью функций Module32First и Module32Next.

Получение списка и свойств окон

Список окон, созданных процессом, получается с помощью функции EnumWindows. Эта функция позволяет получить список всех окон верхнего уровня (т.е. расположенных непосредственно на рабочем столе). Для каждого из этих окон с помощью функции GetWindowThreadProcessID определяется идентификатор процесса. Окна, не принадлежащие выбранному процессу, отсеиваются.

Для каждого из окон верхнего уровня, принадлежащих процессу, с помощью функции EnumChildWindows ищутся дочерние окна, а для каждого из найденных таким образом дочерних окон - его дочерние окна. Здесь следует учесть, что EnumChildWindows возвращает не только дочерние окна заданного окна, но и все окна, которыми владеют эти дочерние окна. Чтобы в дереве окон не было дублирования, при построении очередного уровня дерева окон отбрасываются все окна, непосредственным родителем которых не является данное окно.

Для получения названия окна существует два способа - через функцию GetWindowText и через сообщение WM_GetText. Функция GetWindowText безопасна при использовании с зависшими приложениями - она гарантирует, что вызвавшее её приложение не зависнет само, пытаясь получить ответ от зависшего приложения. Но эта функция не всегда может получить названия элементов управления, расположенных в окнах чужих приложений (точнее, в MSDN написано, что она вообще не может получать названия элементов управления в чужих окнах, но практика показывает, что нередко GetWindowText всё же делает это). При получении названия окна с помощью WM_GetText ограничений на работу с чужими элементами управления нет, но и гарантии, что из-за отсутствия ответа от чужого приложения программа не зависнет, тоже нет.

В данном примере используются оба способа получения текста. При построении дерева всех окон выбранного процесса используется функция GetWindowText, при получении параметров выбранного окна - сообщение WM_GetText. Чтобы программа не зависала, вместо SendMessage для отправки WM_GetText используется SendMessageTimeout.

Для каждого окна программа выводит имя оконного класса и реальный класс окна. В большинстве случаев эти два класса совпадают. Они различаются только для тех окон, чьи классы "унаследованы" от стандартных классов, таких как EDIT, COMBOBOX и т.п.

Вообще, наследования оконных классов в Windows нет. Но существует один нехитрый приём, который позволяет имитировать наследование. Оконная процедура обычно не обрабатывает все сообщения, а передаёт часть их в одну из стандартных оконных процедур (DefWindowProc, DefFrameProc и т.п.). Программа может узнать адрес оконной процедуры, назначенной стандартному классу, с помощью функции GetClassInfo, и использовать эту процедуру вместо стандартной оконной процедуры. Так как большая часть свойств окна определяется тем, как и какие сообщения оно обрабатывает, использование оконной процедуры другого класса позволяет почти полностью унаследовать свойства этого класса. В VCL для наследования оконных классов существует метод TWinControl.CreateSubClass. Функция RealGetWindowClass позволяет узнать имя класса-предка, если такой имеется.

У окна, если оно имеет стиль WS_Child, должно быть родительское окно. Если такого стиля нет, окно располагается непосредственно на рабочем столе. Кроме того, такое окно может (но не обязано) иметь владельца. Получить дескриптор родительского окна можно с помощью функции GetParent. Владельца - с помощью функции GetWindow с параметром GW_Owner.

Примечание: кроме функции GetParent существует также функция GetAncestor, которая также возвращает дескриптор родительского окна, если она вызвана с параметром GA_Parent. Разница между этими функциями заключается в том, что для окон верхнего уровня (т.е. расположенных непосредственно на рабочем столе) GetParent возвращает 0, а GetAncestor - дескриптор рабочего стола (этот дескриптор можно получить через функцию GetDesktopWindow).

Значительную часть кода программы составляет анализ того, какие флаги присутствуют в стиле окна. В этом анализе нет ничего сложного, но он громоздкий из-за большого количества флагов. Следует также учесть, что для стандартных классов одни и те же числовые значения могут иметь разный смысл. Так, например, константы ES_NoHideSel и BS_Left имеют одинаковые значения. Поэтому при расшифровке стиля следует также учитывать класс окна.



К материалу прилагаются файлы:


Смотрите также материалы по темам:
[Параметры процесса/приложения] [Стандартные элементы управления] [Работа с контролами чужого приложения] [Отправка и получение сообщений] [Классы и стили окон] [WM_GETTEXT ] [WM_GETTEXTLENGTH ]

 Обсуждение материала [ 13-06-2008 13:58 ] 8 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования