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

на главную

Жанры

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

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

Шрифт:

Еще несколько слов о числовых константах. В справке можно встретить числа вида, например,

0xC56F
или
0x3341
. Префикс
в C/C++ означает шестнадцатеричное число. В Delphi его следует заменить на
$
, т.е. эти числа должны быть записаны как
$C56F
и
$3341
соответственно.

1.1.3. Дескрипторы вместо классов

Программируя в Delphi, мы быстро привыкаем к тому, что каждый объект реализуется экземпляром соответствующего класса. Например, кнопка реализуется экземпляром класса

TButton
, контекст устройства — классом
TCanvas
. Но когда создавались первые версии Windows, объектно-ориентированный
метод программирования еще не был общепризнанным, поэтому он не был реализован. Современные версии Windows частично унаследовали этот недостаток, поэтому в большинстве случаев приходится работать "по старинке", тем более что DLL могут экспортировать только функции, но не классы. Когда мы будем говорить об объектах, создаваемых через Windows API, будем подразумевать не объекты в терминах ООП, а некоторую сущность, внутренняя структура которой скрыта от нас, поэтому с этой сущностью мы можем оперировать только как с единым и неделимым (атомарным) объектом.

Каждому объекту, созданному с помощью Windows API, присваивается уникальный номер (дескриптор). Его конкретное значение не несет для программиста никакой полезной информации и может быть использовано только для того, чтобы при вызове функций из Windows API указывать, с каким объектом требуется выполнить операцию. В большинстве случаен дескрипторы представляют собой 32-значные числа, а значит, их можно передавать везде, где требуются такие числа. В дальнейшем мы увидим, что Windows API несколько вольно обращается с типами, т.е. один и тот же параметр в различных ситуациях может содержать и число, и указатель, и дескриптор, поэтому знание двоичного представления дескриптора все-таки приносит программисту пользу (хотя если бы система Windows была "спроектирована по правилам", тип дескриптора вообще не должен был интересовать программиста).

Таким образом, главное различие между методами класса и функциями Windows API заключается в том. что первые связаны с тем экземпляром класса, через который они вызываются, и поэтому не требуют явного указания на объект. Вторым необходимо указание объекта через его дескриптор, т.к. они сами по себе никак не связаны ни с одним объектом. Компоненты VCL нередко являются оболочками над объектами Delphi. В этом случае они имеют свойство (которое обычно называется

Handle
), содержащее дескриптор соответствующего объекта. Иногда класс Delphi инкапсулирует несколько объектов Windows. Например, класс
TBitmap
включает в себя
HBITMAP
и
HPALETTE
— картинку и палитру к ней. Соответственно, он хранит два дескриптора: в свойствах
Handle
и
Palettе
.

Следует учитывать, что внутренние механизмы VCL не могут включиться, если изменение объекта происходит через Windows API. Например, если спрятать окно не с помощью метода

Hide
, а путем вызова функции Windows API
ShowWindow(Handle, SW_HIDE)
, не возникнет событие
OnHide
, потому что оно запускается теми самыми внутренними механизмами VCL. Но такие недоразумения случаются обычно только тогда, когда функциями Windows API дублируется то, что можно сделать и с помощью VCL.

Все экземпляры классов, созданные в Delphi, должны удаляться. В некоторых случаях это происходит автоматически, а иногда программист должен сам позаботиться о "выносе мусора". Аналогичная ситуация и с объектами, создаваемыми в Windows API. Если посмотреть справку по функции, создающей какой-то объект, то там обязательно будет информация о том. какой функцией можно удалить объект и нужно ли это делать вручную, или система сделает это автоматически. Во многих случаях совершенно разные объекты могут удаляться одной и той же функцией. Так, функция

DeleteObject
удаляет косметические перья, геометрические перья, кисти, шрифты, регионы, растровые изображения и палитры. Обращайте внимание на возможные исключения. Например, регионы не удаляются системой автоматически, однако если вызвать для региона функцию
SetWindowRgn
, то он переходит в собственность операционной системы. Никакие дальнейшие операции с ним, в том числе и удаление, совершать нельзя.

Если системный объект используется только одним приложением, то он будет удален при завершении работы приложения. Тем не менее хороший стиль программирования требует, чтобы программа удаляла объекты явно, а не полагалась на систему.

1.1.4.

Формы VCL и окна Windows

Под словом "окно" обычно подразумевается некоторая форма наподобие тех, что можно создать с помощью класса

TForm
. Однако это понятие существенно шире. В общем случае окном называется любой объект, который имеет экранные координаты и может реагировать на мышь и клавиатуру. Например, кнопка, которую можно создать с помощью класса
TButton
, — это тоже окно. VCL вносит некоторую путаницу в это понятие. Некоторые визуальные компоненты VCL не являются окнами, а только имитируют их, как, например,
TImage
. Это позволяет экономить ресурсы системы и повысить быстродействие программы. Механизм этой имитации мы рассмотрим позже, а пока следует запомнить, что окнами являются только те визуальные компоненты которые имеют в числе предков класс
TWinControl
. Разработчики VCL постарались, чтобы разница между оконными и неоконными визуальными компонентами была минимальной. Действительно, на первый взгляд неоконный
TLabel
и оконный
TStaticText
кажутся практически близнецами. Разница становится заметной тогда, когда используется Windows API. С неоконными компонентами можно работать только средствами VCL, они даже не имеют свойства
Handle
, в то время как оконными компонентами можно управлять с помощью Windows API.

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

TLabel
, размещенный на форме, не может закрывать собой часть кнопки
TButton
, потому что
TLabel
рисуется на поверхности формы, а кнопка — это независимый объект, лежащий на форме и имеющий свою поверхность. A
TStaticText
может оказаться над кнопкой, потому что он тоже находится над формой.

Примечание

Чтобы разместить неоконный визуальный компонент над оконным, если в этом есть необходимость, можно поступить следующим образом. Положить на форму панель (

TPanel
) — она является оконным компонентом и может быть размещена поверх других оконных элементов. На панель теперь можно положить любой неоконный визуальный компонент, и он будет рисоваться не на поверхности формы, а на поверхности панели. Если теперь убрать у панели рамку и уменьшить ее до размеров содержащегося в ней неоконного компонента, панель станет незаметной, и все вместе это будет выглядеть так, будто неоконный компонент находится над оконным.

Каждое окно принадлежит к какому-то оконному классу. Не следует путать оконный класс с классами Delphi. Это некий шаблон, определяющий базовые свойства окна. Каждому такому шаблону присваивается имя, уникальное в его области видимости. Перед использованием класс необходимо зарегистрировать (функция

RegisterClassEx
). В качестве параметра эта функция принимает запись типа
TWndClassEx
, поля которой содержат параметры класса. 

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

Примечание

Здесь следует отметить некоторую путаницу в терминах. В англоязычной справке есть слово module, служащее для обозначения файла, отображенного в адресное пространство процесса, т.е., в первую очередь, exe-файла, породившего процесс, и загруженных им DLL. И есть слово unit, которое обозначает модуль в Delphi и которое также переводится как модуль. Ранее мы говорили о модулях как об отображаемых в адресное пространство файлах — это они имеют дескрипторы. Модули Delphi не являются системными объектами и дескрипторов не имеют.

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

Прометей: повелитель стали

Рави Ивар
3. Прометей
Фантастика:
фэнтези
7.05
рейтинг книги
Прометей: повелитель стали

Гром над Академией Часть 3

Машуков Тимур
4. Гром над миром
Фантастика:
фэнтези
5.25
рейтинг книги
Гром над Академией Часть 3

Уязвимость

Рам Янка
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Уязвимость

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников

Законы рода

Flow Ascold
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Законы рода

«Три звезды» миллиардера. Отель для новобрачных

Тоцка Тала
2. Три звезды
Любовные романы:
современные любовные романы
7.50
рейтинг книги
«Три звезды» миллиардера. Отель для новобрачных

Мимик нового Мира 13

Северный Лис
12. Мимик!
Фантастика:
боевая фантастика
юмористическая фантастика
рпг
5.00
рейтинг книги
Мимик нового Мира 13

Месть за измену

Кофф Натализа
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Месть за измену

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Не грози Дубровскому! Том 11

Панарин Антон
11. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том 11

Наваждение генерала драконов

Лунёва Мария
3. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Наваждение генерала драконов

Огненный князь 4

Машуков Тимур
4. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 4

Мужчина не моей мечты

Ардова Алиса
1. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.30
рейтинг книги
Мужчина не моей мечты

Золушка по имени Грейс

Ром Полина
Фантастика:
фэнтези
8.63
рейтинг книги
Золушка по имени Грейс