КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Внедрение коллекции в компонентС самого начала Delphi создала нам скелет объявления класса TDappledShape и сейчас, наконец, настало время его оживить. Пишем следующее. TDappledShape = class(TShape) private FSpots: TSpotCollection; protected procedure Paint; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Spots: TSpotCollection read FSpots write SetSpots; end; Что мы сделали? Во-первых, ввели в компонент коллекцию (поле FSpots и свойство Spots с методом записи SetSpots). Далее, поскольку коллекция - это объект, то ее надо сначала создать, а затем уничтожить, поэтому замещаем конструктор и деструктор. Наконец, для отрисовки элементов коллекции замещаем метод Paint. И, конечно, чтобы с коллекцией можно было работать в design-time, свойство Spots обязательно должно быть помещено в раздел published. Далее, как обычно - курсор внутрь класса, Ctrl+Shift+C и пишем реализацию. constructor TDappledShape.Create(AOwner: TComponent); begin inherited Create(AOwner); FSpots := TSpotCollection.Create(Self) end; destructor TDappledShape.Destroy; begin FSpots.Free; inherited Destroy end; procedure TDappledShape.Paint; var SaveColor: TColor; SaveStyle: TBrushStyle; i: integer; begin inherited Paint; SaveColor := Canvas.Brush.Color; SaveStyle := Canvas.Brush.Style; Canvas.Brush.Style := bsSolid; for i := 0 to FSpots.Count - 1 do with FSpots.Items[i] do begin Canvas.Brush.Color := Color; Canvas.Ellipse(CenterX - 3, CenterY - 3, CenterX + 3, CenterY + 3) end; Canvas.Brush.Style := SaveStyle; Canvas.Brush.Color := SaveColor end; procedure TDappledShape.SetSpots(const Value: TSpotCollection); begin FSpots.Assign(Value) end; Весь этот код, в общем, очевиден и некоторых комментариев, пожалуй, требует только метод SetSpots. Тем более, что его код опять-таки стандартен для внедренного в компонент объектного свойства, в частности, для свойства-коллекции. Что произойдет, если написать Object1:=Object2 ? Поскольку Object1 и Object2 - это, по сути, указатели, то после прямого копирования значения Object2 в Object1 оба указателя будут ссылаться на один и тот же объект. Если перед этим Object1 указывал на другой объект, то ссылка потеряется и объект «зависнет» в памяти - но никакого копирования «начинки» Object2 в Object1 не произойдет. Чтобы скопировать не адрес объекта, а его «начинку» используется метод Assign. Но мы поместили его вызов внутрь метода записи - а это означает, что обычное присвоение нашей коллекции какого-либо значения скопирует именно элементы, а не адрес присваиваемой коллекции (в самом деле, ведь вместо присвоения компилятор сгенерит вызов метода SetSpots). Вот и все! Теперь осталось только сохранить готовый модуль, вспомнить, что где-то в недрах экрана висит окно пакета HelloWorld, найти его и нажать кнопку Compile. После этого можем с удовольствием пользоваться собственным компонентом с собственной коллекцией.
|