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

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

Жанры

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

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

Шрифт:

В таких элементах управления, как

TListView
и
TTreeView
, тоже существует возможность связывания 4-байтного значения с элементом (см. свойства
TTreeNode.Data
,
TListItem.Data
), но сообщения
TVM_GETITEM
и
LVM_GETITEM
, через которые можно получить значения этих свойств, устроены иначе, поэтому связывание с элементом значения -1 (а также любого другого 4-байтного значения) не приводит к аналогичным проблемам.

3.4.7. Неправильное поведение свойства Anchors

Свойство

Anchors
,
появившееся в Delphi 5, является очень удобным средством управления положением и размерами визуальных компонентов при изменении размера родителя. Однако в тех случаях, когда начальные размеры формы по каким-то причинам не совпадают с установленными при проектировании, задание значения свойства
Anchors
не приносит желаемого эффекта: первоначальное расположение визуальных компонентов на форме соответствует размерам, установленным при проектировании, а не тем, которые реально получила форма. Примеры такого некорректного поведения демонстрирует программа WrongAnchors на компакт-диске.

Программа WrongAnchors — это MDI-приложение, в котором открываются две дочерние формы разных классов:

ChildForm1
(класс
TChildForm1
) и
ChildForm2
(класс
TChildForm2
). Во время проектирования эти две формы выглядят совершенно одинаково, но при запуске программы только вторая форма сохраняет заданные при проектировании размеры, а первая становится больше. При этом панель, лежащая на ней, не адаптирует свои размеры к изменившемуся размеру формы, хотя свойство Anchors обязывает ее к этому (это легко видеть, изменяя размеры формы после ее создания). Самый простой способ борьбы с этой неприятностью — заставить дочернюю MDI-форму иметь такой же начальный размер, какой задан при проектировании.

Дочерняя MDI-форма приобретает отличный от заданного размер потому, что метод

CreateParams
для ширины и высоты окна устанавливает не те значения, которые хранятся в свойствах
Width
и
Height
, а значение
CW_USERDEFAULT
. Это значение говорит системе, что она должна выбрать размеры окна на свое усмотрение. Чтобы этого не происходило, нужно вновь вернуть установленные при проектировании значения ширины и высоты в перекрытом методе
CreateParams
. Именно этим класс
TChildForm2
отличается от
TChildForm1
(листинг 3.59).

Листинг 3.59. Установка значений ширины и высоты, заданных при проектировании

procedure TChildForm2.CreateParams(var Params: TCreateParams);

begin

 inherited CreateParams(Params);

 Params.Width := Width;

 Params.Height : = Height;

end;

Значение

CW_USERDEFAULT
присваивается ширине и высоте окна не только в том случае, если это дочерняя MDI-форма, но и когда значение свойства
Position
формы равно
poDefault
или
poDefaultSizeOnly
. Но в этом случае перекрывать
CreateParams
нет нужды, достаточно просто изменить значение свойства
Position
на другое. Просто необходимо помнить, что если свойство
Position
формы имеет одно из этих значений, свойства
Anchors
лежащих на форме компонентов должны иметь значения по умолчанию. 

Другой случай, когда окно может при создании иметь размеры, отличные от заданных при проектировании, — это когда свойство

WindowState
равно
wsMaximized
. При этом окно растягивается на весь экран. В примере WrongAnchors в
главном меню есть пункты Развернутое окно 1 и Развернутое окно 2, которые открывают диалоговые окна, развернутые на весь экран. Но в первом из этих окон панель опять не адаптируется к новым размеру окна, в то время как во втором — адаптируется, хотя значения свойства
Anchors
у обеих панелей одинаковые. Это происходит потому, что в первом случае значение
wsMaximized
присваивается свойству
WindowState
во время проектирования, и поэтому окно сразу создается развернутым. А во втором случае значение
wsMaximized
присваивается свойству
WindowState
только при обработке события
OnShow
формы, т.е. тогда, когда форма уже создана с заданными при проектировании размерами, но еще не видна на экране. При этом свойство
Anchors
работает так, как требуется. Это и есть решение проблемы — значение свойству WindowState нужно присваивать не во время проектирования, а в обработчике события
OnShow
.

Но самое интересное происходит, если свойство

WindowState
во время проектирования получило значение
wsMaximized
, а свойство
Position
— значение
poDefault
или
poDefaultSizeOnly
. Тогда размеры и положения визуальных компонентов на форме будут адаптированы к размеру, который не совпадает ни с размером развернутой формы, ни с размером, заданным во время проектирования. Если такой форме отменить развертывание на весь экран, то визуальные компоненты получат размеры и положения, установленные в режиме проектирования.

Нельзя сказать, что разработчики Delphi не знакомы с этой проблемой, они даже что-то делают, чтобы ее решить. Начиная с BDS 2006 можно устанавливать значение свойства

WindowState
в режиме проектирования, и визуальные компоненты на такой форме будут вести себя интуитивно ожидаемым образом, т.е. адаптироваться к размеру формы, растянутой на весь экран. Правда, с двумя существенными оговорками. Во-первых, свойство Position формы не должно быть равно
poDefault
или
poDefaultSizeOnly
. Во-вторых, это относится только к главной форме приложения, для всех остальных форм проблема сохраняется. Поэтому пример WrongAnchors будет работать одинаково и в новых версиях Delphi, и в старых — там на весь экран разворачиваются не главные формы.

3.4.8. Ошибка при сравнении указателей на метод

Процедурные типы в Delphi делятся на обычные (унаследованные от Turbo Pascal) и указатели на методы. Первые — что указатели на простые процедуры и функции, вторые — на методы объектов. Чтобы вызвать метод объекта недостаточно знать, где его код располагается в памяти, нужно еще иметь ссылку на конкретный экземпляр класса, к которому относится данный метод (т.е. необходимо значение указателя

Self
, который будет передан в данный метод). Поэтому указатели на методы называются указателями лишь условно: на самом деле это не один указатель, а два (на код и на объект). Размер переменных такого типа равен 8 байтам, в чем нетрудно убедиться с помощью функции
SizeOf
.

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

MethodPtrCmp
на компакт-диске демонстрирует это. На форме этого примера расположены две кнопки класса
TButton
. Обработчик нажатия на первую из них выглядит так, как в листинге 3.60.

Листинг 3.60. Пример неправильного сравнения указателей на метод
Поделиться:
Популярные книги

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье

Шлейф сандала

Лерн Анна
Фантастика:
фэнтези
6.00
рейтинг книги
Шлейф сандала

Отморозки

Земляной Андрей Борисович
Фантастика:
научная фантастика
7.00
рейтинг книги
Отморозки

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

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

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

Новый Рал 7

Северный Лис
7. Рал!
Фантастика:
попаданцы
5.00
рейтинг книги
Новый Рал 7

Камень. Книга вторая

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

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

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

Фею не драконить!

Завойчинская Милена
2. Феями не рождаются
Фантастика:
юмористическая фантастика
5.00
рейтинг книги
Фею не драконить!

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

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

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

Новый Рал 3

Северный Лис
3. Рал!
Фантастика:
попаданцы
5.88
рейтинг книги
Новый Рал 3

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Ворон. Осколки нас

Грин Эмилия
2. Ворон
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ворон. Осколки нас