« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Функция FlushComm

Создание псевдонима с указанием пути к папке с базой

25 советов по оптимизации ASP-приложений

GUID

Функция AccessResource

Прозрачное объединение сетей с помощью мостов

Добавление в отчет областей заголовка и итогов

Неуправляемый или опасный?

Microsoft SQL Server 2005. Обзор продукта

Пять инвариантов ИТ-образования




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 165
Пользователей: 0

Статьи:: Delphi :: Разные статьи :: Создание собственных компонентов



отправить ссылку другу версия для печати  Обсудить на форуме

Создание собственных компонентов



Создание собственных компонентов
Создание собственных компонентов:

Тебе предстоит познакомится с технологией создания собственных компонентов. Я расскажу, как можно создать компонент Delphi (не путай с компонентами ActiveX). В качестве примера я выбрал достаточно простой, но напичканый математикой пример - часы. Наши часы смогут работать как аналоговые и числовые. По этим часам будет Москва сверятся :).

Компоненты - это самая удобная вещь. С самого появления языков программирования, все программеры стремятся добится многократности использования кода. Для этого мы перешли к процедурному программирования, затем к объектному и сейчас нам предлагают перейти к компонентному программированию. То, что предлагает нам MS - использовать компоненты ActiveX я назову настоящей лажей. Эти компоненты требую гемороя для регистрации их на машине клиента, слежка за версиями и многое другое. Borland предложила свои компоненты. По умолчанию они встраиваются прямо в запускной файл и не требуют никакой регистрации и великолепно работают.

Я думаю, что я достаточно расхвалил компоненты Delphi, пора бы и написать один для примерчика.

Для создания нового компонента выбери меню Component-> New Component. Перед тобой откроется окно, как на рис 1.

Logo
Рис 1. Новый компонент

Давай расмотрим каждое окошечко в отдельности:

  • Ancestor type - Тип предка. Это имя объекта, от которого мы порадим наш объект. Это даст нашему объекту все возможности его предка, плюс мы добавим свои. Для часиков нам понадобится TGraphicControl.
  • Class Name - Имя нашего будущего компонента. Я его назвал TGraphicClock.
  • Palette Page - Имя палитры компонентов, куда будет помещён наш компонент после инсталляции. Я оставил значение по умолчанию "Samples". Но ты можешь поместить его даже на закладку "Standart".
  • Unit file name - имя и путь к модулю, где будет располагатся исходный код компонента. Хотябы посмотри под каким именем сохранят твой компонент и где.
  • Search path - Сюда можно даже не заглядывать.

Жмём "ОК" (именно "ОК", а не 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;

Теперь наш компонент сможет генерировать события.

Logo
Рис 2. Помощь

С событиями вроде всё ясно (если нет, то посмотри на исходник в конце статьи). Теперь переходим к свойствам. В разделе 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.

Вот и всё, что я хотел тебе рассказать.

Logo
Рис 3. Установка компонента

Чтобы установить компонент в системе нужно щёлкнуть меню Component->Install Component. Перед тобой появится окно, как на рис 3.

В строке Unit file name нужно указать полный путь к файлу. Для облегчения выбора используй кнопку Browse

Logo
Рис 4. Окно пакета

 справа. Перед тобой появится запрос на компиляцию пакета. Соглашайся. Если запрос не появился, то в любом случае появится окно пакета (рис 4).

В этом окне ты можешь откомпелировать пакет с помощью кнопки Compile и установить в Delphi с помощью Install .

Вот и всё. Наслаждайся новым компонентом в твоей палитре.

На сегодня хватит. Статья и так получилась достаточно большая. Увидимся в следующий раз.

Напоследок у меня есть небольшая просьба. Пиши мне, о чём бы ты хотел прочитать на моих страницах. Некоторые разделы я неуспеваю писать, а некоторые я просто уже не знаю, о чём тебе рассказать. Ты просто пиши мне, а там разберёмся.

 Исходники примера забирай здесь




Рубрика: Разные статьи




Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия