| « Поставить закладку » « Сделать стартовой » | |||
|
|||
|
Создание собственных компонентов
Создание собственных компонентов:
Тебе предстоит познакомится с технологией создания собственных компонентов. Я расскажу, как можно создать компонент Delphi (не путай с компонентами ActiveX). В качестве примера я выбрал достаточно простой, но напичканый математикой пример - часы. Наши часы смогут работать как аналоговые и числовые. По этим часам будет Москва сверятся :). Компоненты - это самая удобная вещь. С самого появления языков программирования, все программеры стремятся добится многократности использования кода. Для этого мы перешли к процедурному программирования, затем к объектному и сейчас нам предлагают перейти к компонентному программированию. То, что предлагает нам MS - использовать компоненты ActiveX я назову настоящей лажей. Эти компоненты требую гемороя для регистрации их на машине клиента, слежка за версиями и многое другое. Borland предложила свои компоненты. По умолчанию они встраиваются прямо в запускной файл и не требуют никакой регистрации и великолепно работают. Я думаю, что я достаточно расхвалил компоненты Delphi, пора бы и написать один для примерчика. Для создания нового компонента выбери меню Component-> New Component. Перед тобой откроется окно, как на рис 1.
Давай расмотрим каждое окошечко в отдельности:
Жмём "ОК" (именно "ОК", а не Install) и получаем созданный Дульфой код: unit GraphicClock;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TGraphicClock = class(TGraphicControl)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TGraphicClock]);
end;
end.
В принципе простейший компонент готов и его можно инсталировать в Дельфу. Но этот компонент ничего не умеет и он пока является полным аналогом своего предка TGraphicControl. Чтобы он стал отличатся, сейчас мы добавим ему разные свойства. Начнём написание нашего компонента с конструктора и деструктора. конструктор - это простая процедура, которая автоматически вызывается при создании компонента. Деструктор - тоже процедура, только она автоматически вызывается при уничтожении компонента. В конструкторе мы проинициализируем все наши переменные, а в деструкторе уничтожим. Итак, напиши в разделе public: constructor Create(AOwner: TComponent); override; Теперь нажми сочетание клавишь CTRL+SHIFT+C. Дельфи сам создаст заготовку для конструктора: constructor TGraphicClock.Create(AOwner: TComponent); begin inherited; end; Поправим её до вот такого вида: constructor TCDClock.Create(AOwner: TComponent); begin //Вызываем конструктор предка inherited Create(AOwner); //Устанавливаем значения ширины и высоты по умолчанию Width := 50; Height := 50; //Устанавливаем переменную ShowSecondArrow в true. //Она будет у нас отвечать за показ секундной стрелки ShowSecondArrow := true; //Инициализируем остальные переменные PrevTime := 0; CHourDiff := 0; CMinDiff := 0; //Инициализируем растры TBitmap, в которых будут хранится //фон и сам рисунок часов. FBGBitmap:= TBitmap.Create; FFont:=TFont.Create;; FBitmap:= TBitmap.Create; FBitmap.Width := Width; FBitmap.Height := Height; //Выставляем формат времени DateFormat:='tt'; //Запускаем таймер Ticker := TTimer.Create( Self); //Интервал работы таймера - одна секунда Ticker.Interval := 1000; //По событию OnTimer будет вызыватсья процедура TickerCall Ticker.OnTimer := TickerCall; //Включаем таймер Ticker.Enabled := true; //Устанавливаем цвета поумолчанию FFaceColor := clBtnFace; FHourArrowColor := clActiveCaption; FMinArrowColor := clActiveCaption; FSecArrowColor := clActiveCaption; end; Ключевое слово inherited вызывает конструктор предка (в нашем случае TGraphicClock). В остальном, я надеюсь, что с конструктором всё ясно. Теперь создадим деструктор. Для этого также опишем его в разделе public: public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
Кстати, ключевое слово override; после имени этих процедур говорит о том, что мы хотим переписать уже существующую у предка функцию с таким именем. Теперь жмём Ctrl+Shift+C и получаем заготовку для деструктора и поправляем её до вида : destructor TGraphicClock.Destroy; begin Ticker.Free; FBitmap.Free; FBGBitmap.Free; inherited Destroy; end; Заметь, что в конструкторе я вызывал предка в самом начале inherited, а в деструкторе в самом конце. В конструкторе сначала нужно, чтобы проинициализировался предок (он проинициализирует необходимые ссылки), а потом можно инициализировать свои вещи. Если в деструкторе мы сначала вызовем предка, то последующая работа с компонентом уже будет невозможна, потому что предок уничтожит все ссылки, поэтому я ставлю этот вызов в конце. Теперь опишем все необходимые нам переменные в разделе private: private
//Для часов обязательно понадобится таймер
Ticker: TTimer;
//Картинки часов и фона
FBitmap, FBGBitmap: TBitmap;
/События
FOnSecond, FOnMinute, FOnHour: TNotifyEvent;
//Центральная точка
CenterPoint: TPoint;
//Радиус
Radius: integer;
//Остальные параметры, которые мы рассмотрим в процессе.
LapStepW: integer;
PrevTime: TDateTime;
ShowSecondArrow: boolean;
FHourArrowColor,FMinArrowColor, FSecArrowColor: TColor;
FFaceColor: TColor;
CHourDiff, CMinDiff: integer;
FClockStyle:TClockStyle;
FDateFormat: String;
FFont: TFont;
Теперь в разделе private опицем процедуру TickerCall. Мы её уже использовали в конструкторе. Она у нас вызывается по событию от таймера: protected
{ Protected declarations }
procedure TickerCall(Sender: TObject);
Жмём CTRL+SHIAT+C и модифицируем созданную функцию: procedure TCDClock.TickerCall(Sender: TObject); var H,M,S,Hp,Mp,Sp: word; begin //Если компонент создан в дезайнере, то выход if csDesigning in ComponentState then exit; //Иначе это уже запущеная программа //Получить время DecodeCTime( Time, H, M, S); //Получить предыдущее время. DecodeCTime( PrevTime, Hp, Mp, Sp); //Сгенерировать событие OnSecond if Assigned( FOnSecond) then FOnSecond(Self); //Сгенерировать событие OnMinute if Assigned( FOnMinute) AND (Mp < M) then FOnMinute(Self); //Сгенерировать событие OnHour if Assigned( FOnHour) AND (Hp < H) then FOnHour(Self); //Сохранить текущее время в PrevTime PrevTime := Time; if ( NOT ShowSecondArrow) AND (Sp <= S) then exit; //Прорисовать часы. DrawArrows; end; DrawArrows напичкана математикой и она сейчас не имеет для нас особого значения. Немного ниже я приведу её в полном исходнике, а сейчас я просто расказываю тебе о том, как создавать компонента, поэтому мы рассмотрим сабытия генерируемые в функции TickerCall. У нас уже объявлено три события: FOnSecond, FOnMinute, FOnHour: TNotifyEvent; Все они появятся на закладке Events в окне Object Inspector, когда ты поставишь компонент на форму. Чтобы приложения могло поймать эти события, мы объявили переменные типа TNotifyEvent и генерируем эти события (с помощью конструкции типа FOnSecond(Self) для события OnSecond), когда изменилась секунда, изменилась минута или изменился час. Помимо этого, в разделе published мыдолжны описать свойство OnSecond: property OnSecond: TNotifyEvent read FOnSecond write FOnSecond;
property OnMinute: TNotifyEvent read FOnMinute write FOnMinute;
property OnHour: TNotifyEvent read FOnHour write FOnHour;
Теперь наш компонент сможет генерировать события.
С событиями вроде всё ясно (если нет, то посмотри на исходник в конце статьи). Теперь переходим к свойствам. В разделе published мы можем создавать свойства, которые будут отображатся в Object Inspector при выделении наших часиков. Все свойства, которые есть у предка нужно просто описать published
property Align;
property Enabled;
property ParentShowHint;
property ShowHint;
property Visible;
Слово property говорит о том, что мы описываем свойство. Для них не нужны процедуры или функции, потому что эти свойства уже есть у предка. Нам надо только описать их и всё. Я описал только маленькую часть из доступных у TGraphicControl функций. Ты можешь добавить любые из доступных. Чтобы узнать, какие функции можно добавлять, открой помощь (меню Help->Delphi Help) и найди там объект TGraphicControl. Щёлкни по нему дважды и в появившейся справке выбери пункт Properties (вверху окна) (рис 2). Появится окно с перечнем всех свойств. Ты можешь добавить любое из них. Например, чтобы добавить свойство Action нужно написать в разделе published: published
property Action;
Чтобы добавить своё свойство, нужно немного попатеть. Например. Добавим возможность, чтобы пользователь мог менять картинку фона. Для этого описываем в разделе published свойство BGBitmap: //свойство Имя :Тип читать из FBGBitmap записывать с помощью SetBGBitmap property BGBitmap:TBitmap read FBGBitmap write SetBGBitmap; Коментарий поможет тебе разобраться в написанном здесь. Итак, мы объявили свойство BGBitmap типа ТBitmap. Для чтения используется простая переменная FBGBitmap (можно использовать и функцию, но нет смысла, потому что можно прямо читать из переменной), для записи используется процедура SetBGBitmap. Процедура выглядит так: procedure TCDClock.SetBGBitmap(Value: TBitmap); begin FBGBitmap.Assign(Value); invalidate; end; Теперь ты можешь изменять фон простой операцией GraphicClock1.BGBitmap:=bitmap. Если ты хочешь создать свойство с выпадающим списком (как например у свойства Align), по щелчку которого выпадает список возможных параметров, то тут уже немного сложнее. В моих часах есть такой параметр, который делает выбор, какого типа будут часы - аналоговые или цыфровые. Объявление делается так: //свойство Имя :Тип Это нам известно Значение по умолчанию property ClockStyle:TClockStyle read FClockStyle write SetStyleStyle default scAnalog; Мы объявляем свойство ClockStyle типа TClockStyle. Тип TClockStyle мы должны описать в самом начале, до описания нашего объекта TGraphicClock: type
TClockStyle = (scAnalog, scDigital);
TGraphicClock = class(TGraphicControl)
private
Ticker: TTimer;
Строка TClockStyle = (scAnalog, scDigital) - объявляет список переменных, которые и будут выпадать по выбору свойства. Всё остально происходит так же, за исключением нового слова default Которое устанавливает значение по умолчанию - scAnalog. Вот и всё, что я хотел тебе рассказать.
Чтобы установить компонент в системе нужно щёлкнуть меню Component->Install Component. Перед тобой появится окно, как на рис 3. В строке Unit file name нужно указать полный путь к файлу. Для облегчения выбора используй кнопку Browse
справа. Перед тобой появится запрос на компиляцию пакета. Соглашайся. Если запрос не появился, то в любом случае появится окно пакета (рис 4). В этом окне ты можешь откомпелировать пакет с помощью кнопки Compile и установить в Delphi с помощью Install . Вот и всё. Наслаждайся новым компонентом в твоей палитре. На сегодня хватит. Статья и так получилась достаточно большая. Увидимся в следующий раз. Напоследок у меня есть небольшая просьба. Пиши мне, о чём бы ты хотел прочитать на моих страницах. Некоторые разделы я неуспеваю писать, а некоторые я просто уже не знаю, о чём тебе рассказать. Ты просто пиши мне, а там разберёмся. Рубрика: Разные статьи
Вышел MySQL 5.1.30, первый стабильный рели....
После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:
Подробнее... |
Рубрика: MySQL
| Добавлено: 28.11.2008
Тестирование параллельных программ.
Тестирование параллельного программного обеспечения представляет собой более сложную задачу по сравнению с тестированием последовательной программы. Программист должен знать о подводных камнях при тестировании параллельного кода, имеющихся методологиях и инструментарии.
Подробнее... |
Рубрика: Тестирование
| Добавлено: 28.11.2008
Архитектура AMD64 (EM64T).
Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.
Подробнее... |
Рубрика: Архитектура AMD
| Добавлено: 27.11.2008
Остальные статьи: |
Цитата дня (все,добавить):
|
Realcoding.NET
© 2003-2008 |
Контакты |
Реклама на сайте
|