Stdctrls delphi что это

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

Все о программировании.

Главное меню

Перехват классов в Delphi

Вам понадобился специфический компонент в Delphi, типа TButton, но который будет иметь больше свойств или методов, чем стандартная кнопка? Опытные разработчики Delphi, когда им нужен компонент TSuperBtn, применяют два подхода к этой проблеме: ищут готовые сторонние VCL решения или же создают свои собственные компоненты.

Ну а если Вам не нужно, чтобы TSuperBtn находился на Палитре Компонентов и нужен только для этого приложения? Как получить TButton с большим количеством свойств и методов, но не TSuperBtn? И как расширить возможности TButton без необходимости создавать унаследованный класс с другим именем?

Это можно сделать при помощи вспомогательного класса, но вспомогательный класс будет содержать только вновь добавленные свойства и методы.

Большинство начинающих не знают, что они МОГУТ создавать свои собственные пользовательские элементы управления на основе существующего набора VCL, создавая, так называемый класс-перехватчик, который будет иметь то же самое имя, что и основной класс.

Перехватчик классов Delphi

Во-первых, два класса с одним именем можно применять в Delphi, если эти два класса находятся в разных модулях. Поэтому следующее объявление является правильным:

Приведенный выше код создает перехватчик класса для управления TButton, оригинал TButton объявлен в модуле StdCtrls библиотеки VCL.

К тому же это объявление должно быть помещено в отдельный модуль.

И самое главное: модуль перехватчика классов должен быть объявлен ПОСЛЕ перечисления модуля основного класса.

Пример перехватчика класса TButton = class(StdCtrls.TButton)

Вот один перехватчик класса для TButton.

Добавляем новое свойство Text, которое будет хранить строку, а также переопределим процедуру Click, которая будет менять надпись на кнопке, а также выполнять свою основную деятельность.

Теперь поместите кнопку на форму и добавьте модуль Unit2 в конце перечисления модулей в разделе uses, главное, чтобы это было после StdCtrls.

В форме для примера у меня такой код:

При выполнении программы и нажатии на кнопку, кнопка поменяет свою надпись, а форма – заголовок.

Вариантов использования перехватчика классов может быть много, в зависимости от Ваших потребностей и возможностей.

Ну, пожалуй, это все, основные моменты рассмотрены. Если кто и не знал о перехвате классов, то начало положено.

Также заметьте, что это может быть применено не только к компонентам VCL, но и к любым классам Delphi.

Источник

Создание компонентов в Delphi


Автор: Михаил Голованов
http://delphi.mastak.ru
Источник: RSDN Magazine #1-2003

Опубликовано: 27.05.2003
Исправлено: 13.03.2005
Версия текста: 1.0

Процесс построения компонента

В этой статье мы рассмотрим основные стадии построения компонента, сосредоточившись на вопросах конструирования, тестирования и установки компонента в Delphi.

Ниже будут подробно разобраны подготовка каркаса компонента, а также создание свойств, методов и событий компонента.

Мы последовательно рассмотрим все шаги данного процесса на примере Control-а. Любой control является наследником TComponent и шаги по созданию control-ов ничем не отличаются от аналогичных для чистых компонентов, а стало быть, для большей визуальности мы рассмотрим создание именно control-а. Наш компонент будет отличаться от стандартного тем, что по умолчанию цвет текста в нем будет не черным, а синим. Шрифт будет жирным. Кроме того, будут изменены ширина и высота по умолчанию. Данный компонент вряд ли поразит воображение пользователей, однако позволит подробно рассмотреть этапы создания компонента, не увлекаясь его внутренней функциональностью.

Создание модуля компонента. Рекомендации по проектированию.

Создание любого компонента начинается с создания модуля Delphi (файла с расширением pas), в котором будет храниться исходный текст компонента. В одном модуле может содержаться неограниченное количество компонентов. Однако лучше не сваливать все в одну кучу. Во-первых, разделение один модуль – один компонент позволяет нескольким разработчикам параллельно писать компоненты, являющиеся частями одного проекта. Во-вторых, в небольшом модуле гораздо проще разобраться, зная, что он содержит код, относящийся к одному компоненту.

Модуль компонента можно создать вручную или с помощью эксперта построения компонентов.

Первым шагом, независимо от используемого метода, является создание отдельной папки для файлов компонента. Конечно, можно хранить файлы всех компонентов в одной папке, но через некоторое время она превратится просто в свалку.

Начнем с последнего способа, как наиболее часто применяемого.

Stdctrls delphi что это. image001. Stdctrls delphi что это фото. Stdctrls delphi что это-image001. картинка Stdctrls delphi что это. картинка image001
Рисунок 1.

Эксперт (рисунок 1) вызывается с помощью пункта меню Component/New Component в IDE Delphi. Диалоговое окно эксперта содержит следующие поля:

Ancestor type : родительский класс создаваемого компонента. Для выбора родительского класса придерживайтесь простого правила: выбирайте существующий класс компонента, реализующий наибольшую часть требуемой функциональности.

Class Name : имя класса создаваемого компонента. Старайтесь подобрать простое и понятное имя класса, выражающее назначение компонента.

Palette Page: закладка, на которой будет установлен компонент. Можно выбрать из выпадающего списка набор существующих страниц или ввести новое наименование.

UnitFileName: имя модуля, в котором будет размещен исходный текст компонента.

Search Path: пути, в которых среда Delphi будет искать нужные ей файлы для компиляции кода компонента.

Для нашего компонента наиболее близким по функциональности является класс TLabel, он и будет родителем нашего компонента. Часто в качестве родителей следует выбирать не ближайший по функциональности компонент, а ближайший так называемый Custom-компонент. Например, непосредственным предком TLabel является TCustomLabel. Класс TCustomLabel реализует всю функциональность TLabel, однако не выносит объявление многих свойств в секцию published, потому что можно только увеличивать область видимости членов класса, но не уменьшать ее. Критерием для выбора между классом и custom-классом служит необходимость оставить скрытыми от пользователя некоторые поля компонента. Например, в TLabel свойство Align переобъявлено в секции published, тогда как в TCustomLabel оно объявляется как protected. Если не нужно давать пользователю компонента доступ к свойству Align, то в качестве предка можно выбрать класс TCustomLabel. Также заметим, что эксперт предлагает в качестве родителя два класса TLabel. Один из модуля StdCtrls, второй из QStdCtrls. Первый относится к иерархии классов VCL, второй к CLX. В примере мы рассмотрим создание VCL-компонента.

ПРИМЕЧАНИЕ

Как правило, модули исходного кода, начинающиеся с Q, относятся к CLX.

Назовем класс нашего компонента TmgCoolLabel. Размещаться он будет на закладке «Our components». Назовем модуль компонента umgCoolLabel.pas, размещаться он будет в отдельной папке, которую мы создали для него ранее.

Нажав кнопку ОК в окне эксперта, мы получим модуль со следующим текстом:

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

Можно, конечно, написать это все вручную, но радости в этом никакой.

Обратите внимание, что помимо декларации класса, модуль содержит функцию Register. Данная функция вызывается при установке компонента и указывает среде, какие компоненты и каким образом должны быть установлены.

Следующим этапом в разработке компонента является создание свойств, методов и событий. Данный этап наиболее длителен и сложен. Какие свойства, методы и события будет содержать компонент – решать вам, однако можно дать несколько общих рекомендаций.

Я в своей работе использую приведенные ниже соглашения об именовании. Это позволяет упростить поиск нужной информации и не забивать голову придумыванием названия для нового компонента. Вот краткое описание этой конвенции:

Название класса компонента желательно начинать с T, так как в этом случае Delphi при использовании компонента будет автоматически называть экземпляры, отсекая букву T. В противном случае имя экземпляра компонента будет совпадать с именем класса, и лишь цифры в конце имени экземпляра будут указывать пользователям компонента, что это экземпляр, а не класс.

Очень желательно предварять имя класса префиксом. Для компонентов в этой статье я выбрал префикс mg (мои инициалы). Класс нашего компонента будет назваться TmgCoolLabel.

Имя модуля я предваряю префиксом u (сокращение от Unit). Остальная часть имени совпадает с именем класса без буквы T. Данное требование не обязательно, однако поможет вам и вашим коллегам быстро отыскать, в каком модуле объявлен компонент, и не вызовет при этом путаницы.

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

Не принуждайте пользователя выполнять какие-либо дополнительные действия после вызова конструктора компонента. Если пользователь должен будет вызывать какие-либо методы после создания компонента, чтобы привести его в работоспособное состояние, то велика вероятность, что он просто откажется от использования такого компонента.

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

Объявляете методы в секции public только если они выполняют действия, которые полезны пользователям компонента. Все методы, осуществляющие «внутреннюю» работу, прячьте в секциях protected и private.

Не стесняйтесь объявлять свойства. Свойства – основа быстрой и удобной настройки вашего компонента.

События OnChange, Before и After придают компоненту дополнительную гибкость.

Код компонента

Поскольку наш компонент лишь незначительно отличается от предка, нам не придется писать много кода. Достаточно лишь переопределить конструктор компонента, чтобы изменить начальные его настройки и переобъявить свойства ширины и высоты с новыми значениями директивы default.

Главная работа по установке новых начальных значений свойств выполняется в конструкторе Create. Переопределение свойств Height и Width необязательно, но очень желательно. Если этого не сделать, значения по умолчанию для данных свойств будут записываться в файл формы, что будет замедлять загрузку формы.

На практике этап проектирования и кодирования компонента является одним из самых долгих и кропотливых.

Сохранение состояния компонентов

Stdctrls delphi что это. image002. Stdctrls delphi что это фото. Stdctrls delphi что это-image002. картинка Stdctrls delphi что это. картинка image002
Рисунок 2.

Delphi автоматически производит сохранение в файл формы состояния свойств, описанных в области видимости Published. Published – это область видимости, аналогичная директиве public. Помещение декларации элемента класса в секцию published заставляет компилятор добавить дополнительную информацию о типе времени выполнения (run-time type information, RTTI) для данного элемента. По этой причине в секции published могут быть объявлены не все типы данных, а лишь простые типы данных (ordinal datatypes), строки, классы, интерфейсы, указатели на методы и массивы.

В этой статье будет подробно рассмотрен процесс сохранения значений свойств компонентов в файл формы. В большинстве случаев разработчик компонентов может положиться на данный механизм. Но иногда возникают ситуации, когда необходимо вмешаться в процесс сохранения свойств. Чаще всего вмешательство требуется в случае, когда компонент должен сохранить дополнительную информацию или значения свойств, описанных не в разделе published.

На рисунке 1 схематично изображен процесс сохранения свойств формы в файл. Все начинается с того, что IDE Delphi вызывает метод WriteComponentResFile. Метод объявлен следующим образом:

Метод создает файловый поток (TFileStream) и вызывает его метод WriteComponentRes. Метод WriteComponentRes всего лишь вызывает WriteDescendentRes(ResName, Instance, nil). WriteDescendentRes формирует заголовок ресурса компонента и вызывает метод WriteDescendent, который и отвечает за запись свойств компонента в поток.

Код метода WriteDescendent так же прозрачен:

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

Класс TWriter извлекает информацию о свойствах записываемого в поток объекта. Данный класс является наследником абстрактного класса TFiler – базового класса, используемого для записи или чтения информации о свойствах компонента в/из потока.

Рассмотрим класс TFiler более подробно. Задачей этого класса является обеспечение не только записи свойств самого компонента, но и всех компонентов, принадлежащих ему. Класс TFiler является абстрактным, то есть содержит лишь объявления методов и свойств, необходимых для выполнения поставленных задач.

Декларация класса выглядит следующим образом:

Свойство Root содержит указатель на компонент, со свойствами которого мы работаем.

Свойство Ancestor позволяет определить, значения каких свойств должны быть записаны в поток. Дело в том, что необходимо сохранить лишь те свойства, значения которых отличаются от заданных по умолчанию директивой default. Если значение свойства Ancestor равно nil, записываются все свойства, в противном случае проводится анализ необходимости записи. Свойство Ancestor не равно nil лишь в случае сохранения форм, разработанных в визуальном дизайнере.

Свойство IgnoreChildren указывает, нужно ли, помимо свойств самого компонента, записывать свойства компонентов, владельцем которых он является. Если значение свойства равно True, «дети» данного компонента не записываются.

Свойство LookupRoot указывает на локальный корневой (записываемый/считываемый) компонент. Свойство доступно только для чтения и используется для разрешения имен вложенных фреймов. При сохранении или чтении вложенных во фрейм компонентов указывает на этот фрейм.

DefineProperty – метод для чтения/записи значения свойства. Устанавливает указатели на методы чтения и записи свойства с именем, указанным в первом параметре.

DefineBinaryProperty – метод чтения/записи бинарных данных как значений свойства. Устанавливает указатели на методы чтения и записи свойства с именем, указанным в первом параметре.

Класс TFiler имеет двух наследников TWriter и TReader. TWriter отвечает за запись значений свойств, а TReader за чтение.

Наследники добавляют методы чтения и записи различных типов данных.

Загрузка значений свойств происходит аналогично процессу записи. При этом средой Delphi вызывается метод ReadComponentResFile, и создается объект TReader.

Данный механизм применяется при сохранении свойств в файлы формата ресурсов Windows. Последние версии Delphi (6, 7) по умолчанию сохраняют свойства в файлах текстового формата. Преобразования из одного формата в другой можно выполнить глобальными методами ObjectBinaryToText и ObjectTextToBinary.

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

Механизм одинаково работает и для VCL, и для CLX.

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

Загрузка формы в run-time

Stdctrls delphi что это. image003. Stdctrls delphi что это фото. Stdctrls delphi что это-image003. картинка Stdctrls delphi что это. картинка image003
Рисунок 3.

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

Основную работу по загрузке формы выполняет метод ReadFormProperties, а по записи WriteFormProperties. Оба метода осуществляют конвертацию между двоичным и текстовым представлением свойств формы, используя для этого два потока и вызовы ObjectBinaryToText и ObjectTextToBinary.

Запустим приложение. При нажатии на кнопку LoadForm создается второй экземпляр главной формы приложения. Отредактировав во время выполнения программы файл формы (Unit1.dfm) в текстовом редакторе, и снова нажав кнопку LoadForm, можно убедиться, что сделанные изменения отражаются на внешнем виде формы. Нажатие кнопки SaveForm записывает форму в указанный файл.

Сохранение непубликуемых или нестандартных свойств компонентов

Рассмотрим пример сохранения значения непубликуемого (не published) свойства. Наш компонент будет сохранять историю изменений во время проектирования своего свойства Text, и использовать эту историю на этапе выполнения программы. Вот код данного компонента.

Итак, для хранения истории изменений на этапе проектирования свойства Text компонент имеет свойство property TextHistory : TStrings read FTextHistory;

Метод SetText, отвечающий за установку значения свойства Text, сохраняет старое значение. При сохранении формы необходимо сохранить историю изменений, а при загрузке восстановить ее. Так как свойство TextHistory объявлено в секции public, то автоматически оно сохранено не будет.

Чтобы среда Delphi узнала о необходимости сохранения свойства TextHistory и о том, как это делать, необходимо переопределить метод DefineProperties компонента. Переопределенный метод DefineProperties после вызова метода предка производит вызов:

чтобы указать, какие методы необходимо использовать для загрузки и сохранения свойства TextHistory. Загрузка производится методом ReadTextHistory, а сохранение WriteTextHistory.

Метод ReadTextHistory вызывается в ходе загрузки свойств компонента. В качестве параметра он получает объект Reader : TReader. Метод находит и считывает из потока данных маркер начала списка, затем в цикле загружает строки элементов и считывает маркер окончания списка.

Метод WriteTextHisory отвечает за сохранение свойства TextHistory. В качестве параметра он принимает объект TWriter. Метод записывает маркер начала списка в поток данных, и в цикле сохраняет каждый элемент списка в поток. При достижении конца списка в поток записывается маркер конца списка.

Остается только скомпилировать и зарегистрировать пакет, в который помещен данный компонент.

Для тестирования сохранения свойства создайте новое приложение. На главную форму положите наш компонент TTextLogger. В среде Delphi или текстовом редакторе просмотрите dfm-файл главной формы. Затем измените несколько раз значение свойства Text в инспекторе объектов и убедитесь, что история изменений сохраняется в dfm-файле. Ниже приводится текст dfm-файла после вышеописанных действий.

Как видим, свойство TextHistory действительно сохраняется в файле формы.

Заключение

Конечно, это только введение в такую обширную и многогранную область программирования на Borland Delphi, как создание компонентов. В будущем мы еще не раз вернемся к созданию компонентов Delphi, и обсудим более тонкие моменты этого процесса.

Статья написана на основе материалов новой книги Михаила Голованова, посвященной компонентам Delphi.

Источник

Описание модуля ‘StdCtrls’

***Несколько стандартных элементов управления, используемых в большинстве форм Lazarus

***Этот блок содержит все строки ресурса LCL

***Это устройство создается специально для совместимости с Delphi. Он должен использоваться только для констант и определений типов, включенных в Delphi Windows. Это делается только для compatibiltiy.

***Полезные вспомогательные функции и классы более низкого уровня

***Содержит winapi как функции для совместимости Delphi.

***Это устройство поддерживает и хранит все стандартные ресурсы Lazarus в глобальном списке LazarusResources и предоставляет методы и типы для потоковой передачи компонентов.

***Блок содержит определения для многих основных классов и типов, используемых в графических приложениях

***Определяет классы для действий и списки действий, которые будут использоваться с компонентами LCL

***Этот блок содержит основные классы для визуальных элементов управления.

***Содержит определения и описания для построения форм, которые являются основой графического интерфейса пользователя Lazarus

***Меню для использования в формах, созданных с помощью Lazarus IDE

***Для работы с темами отображения, в основном в среде Windows XP (и более поздних)

***TTextStrings описывает потомка TStrings, который оптимизирован для обработки полного текста как целого (вместо строки за строкой)

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

Источник

Пособие по созданию своих компонент на Delphi

Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.

Пособие по написанию своих компонентов на Дельфи для начинающих

Теперь изучим более сложные вещи:

Почему я сел писать это пособие

Все мои готовые компоненты можно найти на сайте http://MihanDelphi.narod.ru

Для чего нужны компоненты

Шаг 1. Придумывание идеи

Первым шагом нужно ответить себе на вопрос: «Для чего мне этот компонент и что он будет делать?». Затем необходимо в общих чертах продумать его свойства, события, на которые он будет реагировать и те функции и процедуры, которыми компонент должен обладать. Затем очень важно выбрать «предка» компонента, то есть наследником какого класса он будет являться. Тут есть два пути. Либо в качестве наследника взять уже готовый компонент (то есть модифицировать уже существующий класс), либо создать новый класс.

Для создания нового класса можно выделить 4 случая:

1. Создание Windows-элемента управления (TWinControl)

2. Создание графического элемента управления (TGraphicControl)

3. Создание нового класса или элемента управления (TCustomControl)

4. Создание невизуального компонента (не видимого) (TComponent)

Итак, что бы приступить от слов к делу, попробуем сделать какой-нибудь супер простой компонент (только в целях ознакомления с техникой создания компонентов), а потом будем его усложнять.

Шаг 2. Создание пустого модуля компонента

Рассматривать этот шаг я буду исходя из устройства Дельфи 3, в других версиях этот процесс не сильно отличается. Давайте попробуем создать кнопку, у которой будет доступна информация о количестве кликов по ней.

Чтобы приступить к непосредственному написанию компонента, вам необходимо сделать следующее:

Закройте проекты, которые вы разрабатывали (формы и модули)

Перед вами откроется диалоговое окно с названием «New Component»

В поле Ancestor Type (тип предка) выберите класс компонента, который вы хотите модифицировать. В нашем случае вам надо выбрать класс TButton

В поле Class Name введите имя класса, который вы хотите получить. Имя обязательно должно начинаться с буквы «T». Мы напишем туда, например, TCountBtn

В поле Palette Page укажите имя закладки на которой этот компонент появиться после установки. Введем туда MyComponents (теперь у вас в Делфьи будет своя закладка с компонентами!).

Поле Unit File Name заполняется автоматически, в зависимости от выбранного имени компонента. Это путь куда будет сохранен ваш модуль.

В поле Search Path ничего изменять не нужно.

Теперь нажмите на кнопку Create Unit и получите следующее:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TCountBtn = class(TButton)

procedure Register;
begin
RegisterComponents(‘MyComponents’, [TCountBtn]);
end;

Шаг 3. Начинаем разбираться во всех директивах

Что же здесь написано? да собственно пока ничего интересного. Здесь объявлен новый класс TCountBtn и процедура регистрации вашего компонента в палитре компонентов.

Директива Private Здесь вы будете писать все скрытые поля которые вам понадобятся для создания компонента. Так же в этой директиве описываются процедуры и функции, необходимые для работы своего компонента, эти процедуры и функции пользователю не доступны. Для нашего компонент мы напишем туда следующее (запись должна состоять из буквы «F» имени поля: тип этого поля):

Буква «F» должна присутсвовать обязательно. Здесь мы создали скрытое поле Count, в котором и будет храниться число кликов по кнопке.

Директива Protected. Обычно я здесь пишу различные обработчики событий мыши и клавиатуры. Мы напишем здесь следующую строку:

procedure Click; override;

Это указывает на то, что мы будем обрабатывать щелчок мыши по компоненту. Слово «override» указывает на то, что мы перекроем стандартное событие OnClick для компонента предка.

Осталась последняя директива Published. В ней также используется объявления доступных пользователю, свойств и методов компонента. Для того, чтобы наш компонент появился на форме необходимо описать метод создания компонента (конструктор), можно прописать и деструктор, но это не обязательно. Следует обратить внимание на то, что если вы хотите, чтобы какие-то свойства вашего компонента появились в Инспекторе Объектов (Object Inspector) вам необходимо описать эти свойства в директиве Published. Это делается так: property Имя_свойства (но помните здесь букву «F» уже не нужно писать), затем ставиться двоеточие «:» тип свойства, read процедура для чтения значения, write функция для записи значения;. Но похоже это все сильно запутано. Посмотрите, что нужно написать для нашего компонента и все поймете:

constructor Create(aowner:Tcomponent);override; //Конструктор
property Count:integer read FCount write FCount; //Свойство Count

Итак все объявления сделаны и мы можем приступить к написанию непосредственно всех объявленных процедур.

Шаг 4. Пишем процедуры и функции.

Начнем с написания конструктора. Это делается примерно так:

constructor TCountBtn.Create(aowner:Tcomponent);
begin
inherited create(Aowner);
end;

Здесь в принципе понимать ничего не надо. Во всех своих компонентах я писал именно это (только класс компонента менял и все). Также сюда можно записывать любые действия, которые вы хотите сделать в самом начале работы компонента, то есть в момент установки компонента на форму. Например можно установить начальное значение нашего свойства Count. Но мы этого делать не будем.

Теперь мы напишем процедуру обработки щелчка мышкой по кнопке:

procedure Tcountbtn.Click;
begin
inherited click;
FCount:=FCount+1;
end;

«Inherited click» означает, что мы повторяем стандартные методы обработки щелчка мышью (зачем напрягаться и делать лишнюю работу:)).

У нас осталась последняя процедура ShowCount. Она может выглядеть примерно так:

procedure TCountBtn.ShowCount;
begin
Showmessage(‘По кнопке ‘+ caption+’ вы сделали: ‘+inttostr(FCount)+’ клик(а/ов)’);
end;

Здесь выводится сообщение в котором показывается количество кликов по кнопке (к тому же выводится имя этой кнопки, ну это я добавил только с эстетической целью).

И если вы все поняли и сделали правильно, то у вас должно получится следующее:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
TCountBtn = class(TButton)
private
< Private declarations >
FCount:integer;
protected
< Protected declarations >
procedure Click;override;
public
< Public declarations >
procedure ShowCount;
published
< Published declarations >
property Count:integer read FCount write FCount;
constructor Create(aowner:Tcomponent);override;
end;

procedure Register;
begin
RegisterComponents(‘Mihan Components’, [TCountBtn]);
end;

constructor TCountBtn.Create(aowner:Tcomponent);
begin
inherited create(Aowner);
end;

procedure Tcountbtn.Click;
begin
inherited click;
FCount:=FCount+1;
end;

procedure TCountBtn.ShowCount;
begin
Showmessage(‘По кнопке ‘+ caption+’ вы сделали: ‘+inttostr(FCount)+’ клик(а/ов)’);
end;
end.

Скорее сохраняйтесь, дабы не потерять случайным образом байты набранного кода:)).

Шаг 5. Устанавливаем компонент

В поле Unit File Name напишите имя вашего сохранненого модуля (естественно необходимо еще и указать путь к нему), а лучше воспользуйтесь кнопкой Browse и выберите ваш файл в открывшемся окне.

В Search Path ничего изменять не нужно, Делфьи сама за вас все туда добавит.

В поле Package File Name выберите имя пакета, в который будет установлен ваш компонент. Мы согласимся с предложенным по умолчанию пакетом.

Теперь нажимаем кнопочку Ok. И тут появиться предупреждение Package dclusr30.dpk will be rebuilt. Continue? Дельфи спрашивает: «Пакет такой-то будет изменен. Продолжить?». Конечно же надо ответить «Да». И если вы все сделали правильно, то появиться сообщение, что ваш компонент установлен. Что ж можно кричать Ура! Это ваш первый компонент.

Создание свойств своего типа

Для начале нам необходимо объявить новый тип. Описание типа нужно добавить после слова Type. Вот так это выглядело вначале:

type
TCountBtn = class(TButton)

Вот так это должно выглядеть:

TShowTp = (Normal, CountToCaption);

Здесь мы объявили новый тип TShowTp, который может принимать только два значения. Все значения, которые вы хотите добавить перечисляются через запятую.

Теперь нам понадобиться создать поле этого типа. Это мы уже умеем и делать и поэтому не должно вызвать никаких сложностей. В директиву Private напишите:

Мы создали поле ShowType, типа TShowTp.

Конечно же необходимо добавить это свойство в инспектор объектов:

property ShowType: TshowTp read FshowType write FShowType;

Ну и наконец, чтобы наш компонент реагировал на изменение этого свойства пользователем надо слегка изменить обработчик события OnClick. После небольшой модификации он может иметь примерно такой вид:

procedure Tcountbtn.Click;
begin
inherited click;
FCount:=Fcount+1;
if ShowType = Normal then
Caption:=Caption;
if ShowType = CountToCaption then
Caption:=’Count= ‘+inttostr(count);
end;

Объясню что произошло. Вначале мы увеличиваем счетчик на единицу. Затем проверяем какое значение имеет свойство ShowType. Если Normal, то ничего не делаем, а если CountToCaption, то в надпись на кнопке выводим количество кликов. Не так уж и сложно как это могло показаться с первого раза.

Имплантируем таймер в компонент

Очень часто бывает, что вам необходимо вставить в компонент, какой-нибудь другой компонент, например, таймер. Как обычно будем рассматривать этот процесс на конкретном примере. Сделаем так, что через каждые 10 секунд значение счетчика кликов будет удваиваться. Для этого мы встроим таймер в нашу кнопку. Нам понадобиться сделать несколько несложных шагов.

После раздела uses, где описаны добавленные в программу модули, объявите переменную типа TTimer. Назовем ее Timer. Приведу небольшой участок кода:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

var Timer: TTimer;
type

Дальше в директиву Protected необходимо добавить обработчик события OnTimer для нашего таймера. Это делается так:

procedure OnTimer(Sender: TObject);

Поскольку наш таймер это не переменная, а компонент, его тоже надо создать, для этого в конструктор нашей кнопки напишем:

constructor TCountBtn.Create(aowner:Tcomponent);
begin
inherited create(Aowner);
Timer:=TTimer.Create(self);
Timer.Enabled:=true;
Timer.OnTimer:=OnTimer;
Timer.Interval:=10000;
end;

Здесь создается экземпляр нашего таймера и его свойству Iterval (измеряется в миллисекундах) присваивается значение 10000 (то есть 10 секунд если по простому).

Собственно осталось написать саму процедуру OnTimer. Я сделал это так:

procedure TCountBtn.OnTimer(Sender: TObject);
begin
FCount:=FCount*2;
end;

Вот примерно то, что у вас должно получиться в конце:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

var Timer: TTimer;
type
TShowTp = (Normal, CountToCaption);
TCountBtn = class(TButton)

FCount:integer;
FShowType:TShowTp;
protected
< Protected declarations >
procedure OnTimer(Sender: TObject);
procedure Click;override;
public
< Public declarations >
procedure ShowCount;
published
< Published declarations >
property Count:integer read FCount write FCount;
constructor Create(aowner:Tcomponent);override;
property ShowType: TshowTp read FshowType write FShowType;
end;

procedure Register;
begin
RegisterComponents(‘Mihan Components’, [TCountBtn]);
end;

constructor TCountBtn.Create(aowner:Tcomponent);
begin
inherited create(Aowner);
Timer:=TTimer.Create(self);
Timer.Enabled:=false;
Timer.OnTimer:=OnTimer;
Timer.Interval:=1000;
end;

procedure Tcountbtn.Click;
begin
inherited click;
FCount:=Fcount+1;
Timer.Enabled:=true;
if ShowType = Normal then
Caption:=Caption;
if ShowType = CountToCaption then
Caption:=’Count= ‘+inttostr(count);
end;

procedure TCountBtn.ShowCount;
begin
Showmessage(‘По кнопке ‘+ caption+’ вы сделали: ‘+inttostr(FCount)+’ клик(а/ов)’);
end;

procedure TCountBtn.OnTimer(Sender: TObject);
begin
FCount:=FCount*2;
end;

Если у вас что-то не сработало, то в начале проверьте все ли у вас написано правильно. Затем проверьте может у вас не хватает какого-нибудь модуля в разделе Uses.

Переустановка компонента

Очень часто бывает необходимо переустановить ваш компонент. Если вы попробуете сделать это путем выбора Component->Install Component, то Дельфи вас честно предупредит о том, что пакет уже содержит модуль с таким именем. Перед вами открывается окно с содержимым пакета. В нем вы должны найти имя вашего компонента и удалить его (либо нажать кнопочку Remove). Теперь в пакете уже нет вашего компонента. Затем проделайте стандартную процедуру по установке компонента.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *