Чтение онлайн

на главную - закладки

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

Все, что делает этот обработчик, — это очищает компонент

TreeWindows
и вызывает
EnumWindows
, передавая ей функцию обратного вызова
EnumWindowsProc
, в которой и выполняется основная работа. Сразу отметим, что в этом примере мы будем использовать одну и ту же функцию обратного вызова как для
EnumWindows
, так и для
EnumWindowsProc
. Сама функция обратного вызова выглядит следующим образом (листинг 1.22).

Листинг 1.22.
Функция обратного вызова
EnumWindowsProc
(первый вариант)

// Это функция обратного вызова, которая будет

// использоваться при вызове EnumWindows и EnumChildWindows.

// Тип второго параметра не совпадает с типом, который

// указан MSDN. Однако TTreeNode, как и любой класс,

// является указателем, поэтому может использоваться везде,

// где требуется нетипизированный указатель - на двоичном

// уровне между ними нет разницы. Указатель на функцию

// обратного вызова в EnumWindows и EnumChildWindows в

// модуле Windows.dcu объявлен как нетипизированный

// указатель, поэтому компилятор не контролирует

// соответствие реального прототипа заявленному.

function EnumWindowsProc(Wnd: HWND; ParentNode: TTreeNode): Bool; stdcall;

 // Система не предусматривает возможности узнать, какова

 // длина имени класса, поэтому при получении этого имени

 // приходится выделять буфер большой длины в надежде, что

 // имя класса не окажется еще длиннее. В данном примере

 // размер этого буфера определяется константой ClassNameLen.

 // Крайне маловероятно, что имя класса скажется длиннее,

 // чем 511 символов (512-й зарезервирован для завершающего

 // нулевого символа).

const

 ClassNameLen = 512;

var

 // Здесь будет храниться заголовок окна

 Text: string;

 TextLen: Integer;

 // Это - буфер для имени класса

 ClassName: array[0..ClassNameLen - 1] of Char;

 Node: TTreeNode;

 NodeName: string;

begin

 Result := True;

 // Функция EnumChildWindows перечисляет не только

 // непосредственно дочерние окна данного окна, но и

 //
дочерние окна его дочерних окон и т.п. Но при

 // построении дерева на каждом шаге нам нужны только

 // прямые потомки, поэтому все окна, не являющиеся прямыми

 // потомками, мы здесь игнорируем.

 if Assigned(ParentNode) and (GetParent(Wnd) <> HWND(ParentNode.Data)) then Exit;

 // Получаем длину заголовка окна. Вместо функций

 // GetWindowText и GetWindowTextLength мы здесь

 // используем сообщения WM_GETTEXT и WM_GETTEXTLENGTH,

 // потому что функции, в отличие от сообщений, не

 // умеют работать с элементами управления,

 // принадлежащими окнам чужих процессов.

 TextLen := SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0);

 // Устанавливаем длину строковой переменной, которая

 // будет служить буфером для заголовка окна.

 // Использование SetLength гарантирует, что будет

 // выделена специальная область памяти, на которую не

 // будет других ссылок.

 SetLength(Text, TextLen);

 // Если заголовок окна - пустая строка, TextLen будет

 // иметь значение 0, и указатель Text при выполнении

 // Set Length получит значение nil. Но при обработке

 // сообщения WM_GETTEXT оконная процедура в любом случае

 // попытается записать строку по переданному адресу,

 // даже если заголовок окна пустой - в этом случае в

 // переданный буфер будет записан один символ -

 // завершающий ноль. Но если будет передан nil, то

 // попытка записать что-то в такой буфер приведет к

 // Access violation, поэтому отправлять окну WM_GETTEXT

 // можно только в том случае, если TextLen > 0.

 if TextLen > 0 then

SendMessage(Wnd, WM_GETTEXT, TextLen + 1, LParam (Text));

 // Заголовок окна может быть очень длинным - например, в

 // Memo заголовком считается весь текст, который там

 // есть. Практика показывает, что существуют проблемы

 // при добавлении в TTreeView узлов с очень длинным

 // названиями: при попытке открыть такой узел программа,

Поделиться:
Популярные книги

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

30 сребреников

Распопов Дмитрий Викторович
1. 30 сребреников
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
30 сребреников

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Охота на разведенку

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
6.76
рейтинг книги
Охота на разведенку

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Возвышение Меркурия. Книга 4

Кронос Александр
4. Меркурий
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 4

Надуй щеки! Том 3

Вишневский Сергей Викторович
3. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 3

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

По воле короля

Леви Кира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
По воле короля

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»