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

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

Жанры

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

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

Шрифт:

 Text := StrAlloc(TextLen);

 try

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

// выделен хотя бы один байт, здесь можно отправлять

// WM_GETTEXT, не проверяя длину строки, как это было

// в предыдущем варианте - буфер всегда будет

// корректным.

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

// Обрезаем слишком длинною строку. Модифицировать

// PChar сложнее, чем string. Вставка нуля в середину

//
строки приводит к тому, что все API-функции будут

// игнорировать "хвост", но на работу StrDispose это не

// повлияет, т.к. функция StrAlloc (а также прочие

// функции выделения памяти для нуль-терминированных

// строк модуля SysUtils) сохраняет размер выделенной

// памяти рядом с самой строкой, и StrDispose

// ориентируется именно на этот размер, а не на

// завершающий ноль.

if TextLen > 104 then

begin

(Text + 104)^ := #0;

(Text + 103)^ := '.';

(Text + 102)^ := '.';

(Text + 101)^ := '.';

(Text + 100)^ := ' ';

end;

GetClassName(Wnd, ClassName, ClassNameLen);

if Text^ = #0 then NodeName := 'Без названия (' + ClassName + ') '

else NodeName := Text + ' (' + ClassName + ');

Node := FormWindows.TreeWindows.Items.AddChild(ParentNode, NodeName);

Node.Data := Pointer(Wnd);

EnumChildWindows(Wnd, @EnumWindowsProc, LParam(Node));

 finally

// Вручную освобождаем память, выделенную для буфера

StrDispose(Text);

 end;

end;

Второй вариант функции

EnumWindowsProc
отличается от первого только тем что для организации буфера для получения имени окна вместо переменной типа
string
используется переменная типа
PChar
. Соответственно, все манипуляции с динамической памятью теперь выполняются вручную, а просто отсечь конец слишком длинной строки и прибавить к результату другую строку (многоточие) мы не можем, приходится модифицировать строку посимвольно. Тем не менее видно, что и с помощью типа
PChar
задача создания буфера для строки, возвращаемой API-функцией, достаточно легко решается.

1.2.2. Пример Line

Пример Line представляет собой невизуальный компонент

TLine
, который перехватывает оконные сообщения своего владельца (владельца в терминах VCL, разумеется, раз речь идет о неоконном компоненте). Компонент
TLine
рисует на своем владельце линию из точки (
StartX
,
StartY
) в точку (
EndX
,
EndY
) цветом
Color
. Пользователь может перемещать концы линии мышью. Достаточно разместить компонент
TLine
на форме, и на ней появится линия, которую пользователь может перемещать как во время проектирования формы, так и во время выполнения программы. Можно также разместить на форме, например, панель, и сделать ее владельцем компонента
TLine
— тогда линия будет рисоваться на панели. Но это можно сделать только во время исполнения программы, потому что владельцем всех компонентов, созданных во время проектирования формы, становится сама форма. Чтобы установить компонент,
нужно выполнить следующие действия:

1. Переписать с компакт-диска файлы Line.pas и Line.dcr в папку, где вы храните компоненты. Если такой папки еще нет, самое время создать ее. Где именно она будет расположена, значения не имеет, выбирайте любое удобное для вас место. Главное — это прописать эту папку в путях, где Delphi ищет компоненты. Чтобы сделать это в Delphi 7 и более ранних версиях, откройте меню Tools\Environment Options, в появившемся диалоговом окне выберите закладку Library и добавьте свою папку в поле Library path. В BDS 2006 и выше откройте меню Tools\Options, в появившемся диалоговом окне в дереве в левой части выберите пункт Environment Options\Delphi Options\Library — Win32 и добавьте папку в поле Library path.

2. Создайте новый пакет (меню File\New\Other, в открывшемся окне выбрать Package). После этого в Delphi 7 и более ранних версиях откроется небольшое окно пакета. В BDS 2006 и более поздних версиях окно не откроется, но пакет появится в группе проектов (по умолчанию это окно Project Manager в правом верхнем углу главного окна). Сохраните пакет в ту же папку, где находится Line.pas, под любым именем, кроме Line (иначе будет конфликт имен).

3. Добавьте в пакет файл Line.pas. В BDS 2006 для этого необходимо с помощью правой кнопки мыши вызвать контекстное меню пакета в окне Project Manager и выбрать там пункт Add. В Delphi 7 и более ранних версиях в окне пакета нужно нажать кнопку Add.

4. Установите компонент. В BDS 2006 и выше для этого следует выбрать пункт Install в контекстном меню проекта, а в Delphi 7 и более ранних версиях — нажать кнопку Install в окне пакета. После этого в палитре компонентов у вас появится вкладка Delphi Kingdom Samples, a в ней — компонент TLine.

Если вы не хотите помещать компонент

TLine
в палитру компонентов (или у вас Turbo Delphi Explorer, и вы просто не имеете такой возможности), можно воспользоваться проектом LineSample, который во время выполнения создаёт два экземпляра
TLine
, владельцем одного из которых является форма, другого — панель.

Перехват сообщения владельца осуществляется путем изменения его свойства

WindowProc
— записи в него указателя на свой обработчик сообщений. Здесь можно применить один хитрый прием. Компонент
TLine
не имеет своей оконной процедуры, т.к., будучи прямым наследником класса
TComponent
, окном не является. Но метод
Dispatch
у него есть, поскольку он объявлен в классе
TObject
. В классе
TComponent
и в его предках метод
Dispatch
никогда не вызывается. Если мы напишем обработчик сообщений таким образом, что он будет передавать сообщения методу
Dispatch
, то сможем в нашем компоненте создавать свои методы для обработки сообщений, в которые метод
Dispatch
при необходимости будет передавать сообщения для обработки. Необработанные сообщения при этом будут передаваться в метод
DefaultHandler
, который у класса
TComponent
ничего не делает. Если мы перекроем
DefaultHandler
так, чтобы он вызывал оригинальный обработчик сообщений родителя, то все необработанные сообщения пойдут туда. Более того, вызов
inherited
из методов-обработчиков сообщений тоже будет приводить к вызову оригинального обработчика родителя, т.к. в данном случае
inherited
при отсутствии унаследованного обработчика приводит к вызову
DefaultHandler
. В листинге 1.24 показано объявление класса
TLine
и код его методов, относящихся к перехвату сообщений.

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

Сама себе хозяйка

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

Ученичество. Книга 2

Понарошку Евгений
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученичество. Книга 2

Надуй щеки!

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

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Эволюционер из трущоб. Том 6

Панарин Антон
6. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Эволюционер из трущоб. Том 6

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

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

Гарем на шагоходе. Том 1

Гремлинов Гриша
1. Волк и его волчицы
Фантастика:
боевая фантастика
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Гарем на шагоходе. Том 1

Академия проклятий. Книги 1 - 7

Звездная Елена
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Академия проклятий. Книги 1 - 7

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Сломанная кукла

Рам Янка
5. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сломанная кукла

Офицер-разведки

Поселягин Владимир Геннадьевич
2. Красноармеец
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Офицер-разведки

Имя нам Легион. Том 9

Дорничев Дмитрий
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 9

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Этот мир не выдержит меня. Том 2

Майнер Максим
2. Первый простолюдин в Академии
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Этот мир не выдержит меня. Том 2