О чём не пишут в книгах по 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 узлов с очень длинным
// названиями: при попытке открыть такой узел программа,
Поделиться:
Популярные книги
Ученичество. Книга 1
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Обыкновенные ведьмы средней полосы
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Треск штанов
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Медиум
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
"Фантастика 2023-123". Компиляция. Книги 1-25
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Гром над Тверью
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Идеальный мир для Лекаря 11
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Совок
1. Совок
Фантастика:
фэнтези
детективная фантастика
попаданцы
8.13
рейтинг книги
Табу на вожделение. Мечта профессора
4. Яд первой любви
Любовные романы:
современные любовные романы
5.58
рейтинг книги
Сонный лекарь 4
4. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Огненный князь 4
4. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00