Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
9 Разработка компонентов в среде Delphi.doc
Скачиваний:
7
Добавлен:
20.08.2019
Размер:
948.74 Кб
Скачать

9.3.6. Массив свойств

Определитель Index позволяет разным свойствам иметь один и тот же метод доступа. Его описание состоит из директивы index и последующей за ней константой целого типа в промежутке от -2147483647 до 2147483647. Если у свойства есть определи­тель Index, то определители read и write должны ссылаться на методы, а не на поля. Например:

type

TRectangle = class private

FCoordinates: array[0..3] of Longint;

function GetCoordinate(Index: Integer): Longint;

procedure SetCoordinate{Index: Integer; Value: Longint); public

property Left: Longint index 0 read GetCoordinate

write SetCoordinate; property Top: Longint index 1 read GetCoordinate

write SetCoordinate; property Right: Longint index 2 read GetCoordinate

write SetCoordinate; property Bottom: Longint index 3 read GetCoordinate

write SetCoordinate;

end;

Обращение к свойству, определенному с директивой index, например,

Rectangle.Right := Rectangle.Left + 100;

{Rectangle: TRectangle}

автоматически преобразуется к вызову метода,

Rectangle.SetCoordinate (2, Rectangle.GetCoordinate(0) + 100);

9.3.7. Перекрытие и переопределение свойств

Описание свойства без указания типа называется перекры­тием свойства. Самый простой способ перекрытия состоит в ис­пользовании зарезервированного слова property и идентифика­тора — имени свойства. Данный способ используется для смены видимости свойства.

Перекрытия свойств могут содержать директивы read, write, stored, default и nodefault. Перекрытие может заменить суще­ствующие наследуемые определители доступа, добавить недо­стающие, увеличить видимость свойства, но оно не может уда­лить существующий определитель или уменьшить видимость свойства. Следующий пример демонстрирует использование пе­рекрытия свойств:

type

TAncestor = class

protected

property Size: Integer read FSize; property Text: String read GetText write SetText; property Color: TColor read FColor write SetColor stored False;

...

end;

TDerived = class(TAncestor)

...

protected

property Size write SetSize; published property Text; property Color stored True default clBlue;

end;

Перекрытие свойства Size добавляет определитель write, что позволяет редактировать свойство, а перекрытие свойств Text и Color меняет их видимость с protected на published. Перекры­тие свойства Color указывает, что оно должно быть сохранено, если его значение отлично от clBlue.

Переопределение свойства включает указание его типа, оно скрывает наследуемое свойство. Это означает, что создается но­вое свойство с тем же именем, что и у предка. Любое описание свойства, которое содержит указание типа, должно быть завер­шенным и включать в себя как минимум один определитель до­ступа:

type TAncestor = class

property Value: Integer read Methodl write Method2; end;

TDescendant = class(TAncestor)

property Value: Integer read Method3 write Method4; end;

9.3.8. Создание событий

Событие — это любое происшествие, вызванное вмешатель­ством пользователя, операционной системы или логикой про­граммы. Событие связано с некоторым программным кодом, отвечающим на это происшествие. Совокупность события и кода, выполняющегося в ответ на это событие, называется свойством-событием и реализуется в виде указателя на некото­рый метод. Метод, на который указывает это свойство, называ­ется обработчиком события.

Свойства-события являются не более чем указателями на ме­тоды. В модуле Controls.pas определены стандартные свойст­ва-события.

Описание свойства-события начинается с описания нового типа, который представляет собой процедуру, одним из параметров которой, является Sender типа TObject, а директива of object делает эту процедуру методом:

TMouseMoveEvent = procedure(Sender: TObject; Shift: TShiftState; X, Y: Integer) of object;

Когда происходит какое-либо событие, например, перемеще­ние мыши, в систему Win32 посылается соответствующее сооб­щение, в нашем случае WM_MOUSEMOVE. Система Win32 пе­редает это событие элементу управления, для которого оно предназначено и на которое он должен тем или иным способом ответить. Элемент управления может ответить на это событие, сначала проверив наличие кода, предусмотренного для выпол­нения. Для этого он проверяет, ссылается ли свойство-событие на какой-либо код. Если да, то элемент выполняет этот код, на­зываемый обработчиком события. Операция по определению наличия метода, связанного с событием-свойством, возлагается на метод диспетчеризации. Эти методы объявляются как защи­щенные методы того компонента, которому они принадлежат.

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

TControl = class(TComponent) private

FOnMouseMove: TMouseMoveEvent; {внутреннее поле события} procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;

protected

procedure MouseMove(Shift: TShiftState; X, Y: Integer);

dynamic; {метод диспетчеризации}

property OnMouseMove: TMouseMoveEvent read FOnMouseMove

write FOnMouseMove;

end;

Метод диспетчеризации определяет, существует ли свойство-событие на какой-нибудь метод, и если это так, то передает управление соответствующей процедуре:

procedure TControl.MouseMove(Shift: TShiftState; X, Y: Integer); begin

if Assigned (FOnMouseMove) then FOnMouseMove (Self, Shift, X, Y) ; end;

Чтобы обеспечить возможность переопределения обработки события, необходимо перехватить возникшее событие, обрабо­тать его стандартным образом и передать управление методу диспетчеризации:

procedure TControl.WMMouseMove(var Message: TWMMouseMove); begin inherited; if not (csNoStdEvents in ControlStyle) then

{включение csNoStdEvents во множество ControlStyle заставляет игнорировать стандартные события мыши, клавиатуры. Этот флаг позволяет ускорить запуск приложения, если оно при этом не нуждается в обработке этих событий} with Message do MouseMove(KeysToShiftState(Keys), XPos, YPos) ; end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]