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

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

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

В состав проекта обязательно входят следующие элементы :

· основной файл проекта, имеющий расширение.DPR (D elphi PR oject ). В проекте может существовать только один файл с таким расширением. Это небольшой текстовый файл на языке Object Pascal , который содержит ссылки на все формы проекта и инициализирует приложение;

· файлы всех форм проекта. Для каждой формы формируется пара одноименных файлов – файл Pascal -модуля с обычным расширением.PAS и файл ресурсов формы с расширением.DFM (D elphi F orM ). Любая форма проекта всегда должна иметь свою пару файлов модуль-ресурс. Обратное не обязательно, т.е. проект может включать в себя модули и файлы ресурсов не относящиеся ни к одной из форм приложения;

· файл ресурсов приложения (*.RES). В нем содержатся ресурсы приложения, не вошедшие в формы;

файл опций проекта (*.DOF – D elphi O ptions F ile ). В этом файле сохраняются значения директив и опций компилятора, настроек компоновщика, названия рабочих каталогов, параметры командной строки запуска приложения.

Пример программы

Перед началом работы над очередным проектом, прежде всего, следует создать для файлов будущего проекта отдельную папку (директорию). Это правило необходимо соблюдать всегда, иначе очень скоро файлы различных проектов так “перемешаются” в одном директории, что рассортировать их по проектам станет довольно сложно. Будем считать, в дальнейшем, что такая папка создана, назовем ее PO_EVM , это будет текущая папка проекта.

Запускаем Delphi . Если загрузка прошла успешно, то на экране монитора мы увидим то, что представлено на рис.1. В строке заголовка главного окна Delphi присутствует надпись Delphi 3 – Project1 . Это название нашего проекта и программы. В строке заголовка окна формы приложения написано Form1 . Если нажать клавишу F12 или щелкнуть мышью на кнопку Toggle
Form/Unit
(панель быстрого доступа) или выбрать пункт меню View/Toggle Form/Unit , то окно редактора кода переместится на передний план и мы увидим содержимое страницы Unit1 редактора, в которой представлен Pascal -код модуля Unit1 . Добавим в окно редактора кода еще одну страницу, в которой расположится код основного программы проекта. Для этого выберем пункт меню View/Project Source . Ниже представлено содержимое двух страниц редактора кода: Pascal-код главной программы и Pascal-код модуля главной формы проекта, соответственно.

Сохраним файлы проекта в созданном директории PO_EVM . Для этого нажмем кнопку Save all на панели быстрого доступа или выберем пункт меню File/Save Project As… . В появившемся стандартном Windows- окне сохранения файлов выберем папку PO_EVM и последовательно сохраним Pascal -код модуля формы и Pascal -код программы в файлах с именами IDE_Un1.pas и IDE_Pr.dpr соответственно.

program IDE_Pr;

IDE_Un1 in ‘IDE_Un1.pas’ {Form1};

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

unit IDE_Un1;

Windows, Messages, SysUtils,

lasses, Graphics, Controls,

TForm1 = class(TForm)

{ Private declarations }

{ Public declarations }

Если сейчас посмотреть содержимое папки PO_EVM , то в ней будут находиться следующие файлы проекта: IDE_Pr.dof – файл опций проекта; IDE_Pr.dpr – основной файл проекта; IDE_Pr.res – файл ресурсов проекта; IDE_Un1.pas – файл Pascal-кода модуля формы; IDE_Un1.dfm – файл ресурсов формы.

Желательно изменить некоторые стандартные настройки среды, в частности для того, чтобы на экране отображался процесс компиляции и компоновки программы, а также, чтобы перед каждым запуском программы на исполнение автоматически сохранялись все модифицированные файлы проекта. Сделать это можно в диалоговом окне Environment Options… , которое можно вызвать из меню Tools/ Environment Options… . На страничке Preferences в разделе Desktop contens установить переключатель в положение Desktop only , в разделе Autosave options установить выключатели в пунктах Editor files и Desktop , а в разделе Compiling and Running установить выключатель Show compiler progress .

Простейшая программа в Delphi уже готова к исполнению. Нажав кнопку Run на панели быстрого доступа или клавишу F9 , можно наблюдать процессы компиляции и компоновки программы, после которых начнет исполняться наша программа. Визуально программа представлена на экране пустым окном со стандартной Windows- строкой заголовка, содержащей пиктограмму приложения, наименование формы и три кнопки управления окном. Выход из программы и возврат в среду Delphi осуществляется стандартным для Windows способом – комбинацией клавиш Alt-F4 или нажатием на кнопку закрытия приложения. Если сейчас просмотреть содержимое папки файлов проекта PO_EVM , то можно заметить, что в ней появились еще два файла: IDE_Un1.dcu и IDE_Pr.exe – откомпилированный файл модуля формы и загрузочный (исполняемый) файл приложения. Файл IDE_Pr.exe можно запускать на исполнение автономно, т.е. вне среды Delphi . После выхода из среды Delphi , в папке образуется еще один файл IDE_Pr.dsk – файл с индивидуальными пользовательскими настройками среды.

Приведем примерную последовательность действий программиста, который создает программу “Калькулятор +/- “. Это, с позволения сказать, приложение предназначено для выполнения операций сложения и вычитания вещественных чисел. При запуске окно (форма) программы должно выглядеть как на рис. 7.

На форме расположены три строки ввода/вывода (компоненты типа TEdit ) для ввода двух операндов и вывода результата; пять кнопок (четыре компоненты типа TButton и одна – TBitBtn ) – сброс, указание типа и результата операции (C , + , , = ), выхода из программы (Close); три надписи для обозначения операндов и результата (компоненты типа TLabel ); разделительный интерфейсный элемент для выделения поля вывода результат счета (компонент TBevel ).

В исходном состоянии, после запуска Delphi и сохранении двух файлов проекта с указанными именами, мы имеем пустую форму. Далее порядок построения интерфейсной части приложения был следующим (результаты ваших действий можно сверять с расположением компонентов на рис. 7):

1. Свойство формы Caption в инспекторе объектов изменяем со значения Form1 на строковое значение Калькулятор +/- . Изменение значения названия формы сразу заметно в строке заголовка формы;

2. На странице Standard палитры компонентов щелкаем левой кнопкой мыши на изображении компонента Label , затем перемещаем указатель мыши в район левого верхнего угла формы и щелкаем левой кнопкой там. В этом месте на форме появится изображение компонента Label с надписью Label1 . Изображение компонента выделяется по периметру шестью черными квадратиками – маркерами изменения размеров (размерные маркеры). Выделение маркерами означает, что данный компонент сейчас является активным. С помощью мыши стандартными Windows- приемами можно изменять размеры компонента, перемещать его по форме. Для активизации другого компонента формы необходимо просто щелкнуть на нем левой кнопкой мыши. Содержимое закладок инспектора объектов всегда соответствует активному компоненту, при активизации другого компонента, состав полей инспектора объектов автоматически меняется. Изменим свойство Caption компонента Label со значения Label1 на значение 1-ый операнд . Свойству Name этого компонента придадим значение lb_1 .

3. Действуя аналогично, расположим второй компонент-метку немного ниже первой, задав, соответственно, свойствам Caption и Name значения 2-ой операнд и lb_2 .

4. На той же странице Standard палитры компонентов выберем компонент Edit (строка редактирования) и поместим его на форме правее первой метки. Свойству Name присвоим значение ed_1 , а свойство Text сделаем пустым.

5. Действуя аналогично, расположим вторую строку редактирования правее второй метки, задав, соответственно, свойствам Text и Name значения пустой строки и ed_2 .

6. На странице Additional палитры компонентов выберем компонент Bevel и поместим его так, чтобы он изображал “итоговую” черту под второй меткой и второй строкой ввода. Свойство Name, равное Bevel1 , изменять не будем.

7. Под компонентом Bevel разместим еще одну пару “метка – строка ввода” для вывода результата вычислений. Свойствам Name присвоим значения lb_3 и ed_3 , свойству lb_3.Caption – значение Результат , а свойству Text компонента ed_3 – значение пустой строки.

8. Поместим еще одну метку для изображения текущей арифметической операции: (?, +, –) - операция не определена, операция сложения, операция вычитания. Расположим эту метку между двумя первыми метками, ближе к левым границам компонентов для ввода операндов (см. рис.7). Свойству Name присвоим значение lb_oper , а свойству Caption – значение ? . Установим также подсвойство Size в свойстве Font для этой метки, равным 14 ;

9. Подравняем компоненты. Стандартным Windows- приемом выделим компоненты – метки. Для этого, держа нажатой кнопку Shift , последовательно щелкая левой кнопкой мыши по компонентам-меткам, активизируем одновременно все три метки. Если теперь щелкнуть правой кнопкой мыши, то по законам Windows 95 должно появиться контекстное меню – оно и появляется. Выберем в нем пункт A lign… (выравнивание). Теперь на экране мы видим окно Alignment . Выберем на панели Horizontal пункт Left sides и нажмем кнопку Ok . В результате этого все три компонента – метки выровняются по левой границе самой левой компоненты. Аналогичными действиями подравняем и все три строки редактирования. Строки редактирования можно выровнять и по размерам, выделив их одновременно все три и выбрав в контекстном меню пункт Size… . “Тонкую” работу по изменению размеров и перемещению компонент выполняют обычно не мышью, а клавишами управления курсором при нажатых, соответственно, сдвиговых клавишах Shift и Ctrl . Эти действия можно производить не только с одним компонентом, но и с выделенной группой компонентов.

10. Теперь расставим на форме управляющие кнопки. Их у нас пять (см. рис.7). Первые четыре кнопки – кнопка сброса, кнопки операций (сложение (+) и вычитание (–)) и кнопка результата. Пятая кнопка – кнопка завершения работы программы. На странице Standard палитры компонентов выберем компонент Button (кнопка) и поместим его правее первой строки редактирования. Свойствам Caption и Name кнопки присвоим соответственно значения C и btn_Clear . Аналогичным образом располагаем и три другие кнопки на форме, назвав (свойство Name ) их btn_sum, btn_sub и btn_rez , с наименованиями (свойство Caption ) + , и = (см. рис.7). Выделив кнопки в группу, дважды щелкнем на составном свойстве Font в инспекторе объектов. В поле Size свойства Font зададим размер шрифта 14 пунктов. После установки этого значения размер символов на кнопках увеличится.

11. Пятая кнопка – кнопка завершения программы – выбрана со страницы Additional . Это первый по порядку компонент на этой странице – кнопка типа BitBtn (командная кнопка с надписью и пиктограммой). Расположив кнопку на показано на рис.7, выберем из списка значений свойства Kind значение bkClose . Этим выбором полностью определяются визуальные атрибуты и функциональное назначение кнопки.

12. В заключение процесса построения интерфейсной части программы уменьшим форму до размеров, приведенных на рис.7.

На этом заканчивается первый этап создания приложения – построения интерфейса. Необходимо отметить, что на любом этапе построения интерфейса можно в любой момент запустить программу на исполнение. В процессе выполнения вышеописанных шагов мы не написали ни одной строчки, ни одного Pascal-оператора. Все записи в тексте модуля формы приложения Delphi делает сама. К этому моменту в интерфейсной части модуля формы произошли изменения – добавились описания компонентов, помещенных нами в форму и стандартные модули Delphi – Buttons, StdCtrls, ExtCtrls.

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs,

Buttons, StdCtrls, ExtCtrls;

TForm1 = class(TForm)

lb_Oper: TLabel;

btn_Clear: TButton;

btn_sum: TButton;

btn_sub: TButton;

btn_rez: TButton;

bb_Close: TBitBtn;

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

Сначала словесно оговорим то, что должно происходить при нажатии той или иной кнопки, в каких случаях и какого содержания сообщения должны появляться на экране:

1. Нажатие на кнопку “Очистить” (С ) - очистить все три строки редактирования и в качестве знака операции отобразить знак вопроса (?) ;

2. Нажатие на кнопку “Сложить” (+ ) - изменить изображение знака операции на знак плюс (+) ;

3. Нажатие на кнопку “Вычесть” () - изменить изображение знака операции на знак минус (–) ;

4. Нажатие на кнопку “Вычислить” (= ) - провести проверку на правильность данных в первых двух строках редактирования. Если данные правильные (числа), то провести соответствующую арифметическую операцию и вывести результат в строку вывода. Если обнаружена ошибка в исходных данных, то следует вывести сообщение об этом с указанием места ошибки.

Теперь переведём (транслируем) на Pascal-код каждый из вышеперечисленных пунктов. Каждый компонент имеет список событий (список приводится на второй странице (Events ) инспектора объектов), на которые он может реагировать (которые он может обрабатывать). Наша задача – написать код, который будет выполняться при возникновении того или иного события. Для кнопок в Delphi определены несколько обработчиков событий, нас будет интересовать обработчик события “Однократное нажатие на кнопку” (щелчок левой кнопкой мыши в момент нахождения указателя мыши над компонентом Button ). Этот обработчик называется OnClick . Каждый обработчик события оформляется в отдельную процедуру. Название этой процедуре формирует сама среда Delphi .

Напишем обработчик события однократного нажатия на кнопку “Очистить”. Для этого выделим на форме кнопку “Очистить” (С ). Активизируем страницу Events в окне инспектора объектов. Дважды щелкнем на пустом поле правого столбца рядом с надписью OnClick . После этого Delphi автоматически отображает окно редактора кода IDE_Un1 и помещает текстовый курсор для вставки текста внутри процедуры TForm1.btn_ClearClick:

procedure TForm1.btn_ClearClick(Sender: TObject);

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

lb_Oper.Caption:=’?’; {тип операции неопределен (метка – ?)}

ed_1.Text:=”; {очистить строку для ввода первого операнда}

ed_2.Text:=”; {очистить строку для ввода второго операнда}

ed_3.Text:=”; {очистить строку для вывода результата}

Действуя аналогично, сформируем обработчики события “Однократный щелчок левой кнопкой мыши на компоненте” для интерфейсных кнопок “Сложить” (+ ) и “Вычесть” ():

– для кнопки “Сложить” строка кода - lb_Oper.Caption:=’+’;

– для кнопки “Вычесть” строка кода - lb_Oper.Caption:=’-‘;

Обработчик события OnClick для кнопки “Вычислить” (= ) будет содержать следующий Pascal -код:

procedure TForm1.btn_rezClick(Sender: TObject);

Val(ed_1.Text,r1,i);

if i<>0 then begin

ShowMessage(‘Ошибка в первом операнде’);

Val(ed_2.Text,r2,i);

if i<>0 then begin

ShowMessage(‘Ошибка во втором операнде’);

case lb_oper.Caption of

‘+’ : ed_3.Text:=FloatToStr(r1+r2);

‘-‘ : ed_3.Text:=FloatToStr(r1-r2);

else ShowMessage(‘Не определен тип операции’);

В обработчике события TForm1.btn_rezClick введены две локальных вещественных переменных r1 и r2 для запоминания числовых значений двух операндов и целочисленная переменная i для использования в Pascal -процедуре Val преобразования строковой переменной в числовое представление. Этот обработчик реализует четвертый пункт словесного алгоритма работы программы. Сначала проверяется на правильность строка, введенных пользователем, символов первого операнда. Если это не число, то процедурой ShowMessage выводится соответствующее ситуации сообщение и по процедуре Exit заканчивается выполнение кода процедуры. В случае корректности данных переменная r1 примет числовое значение первого операнда. Аналогичным образом проверяется второй операнд и, если здесь все нормально, то переменная r2 примет числовое значение второго операнда.

Оператор Case реализует арифметическую операцию над переменными r1 и r2 в зависимости от того, какой символ (+ , , ? ) определяет значение свойства Caption метки lb_oper . Если знак арифметической операции не определен (у нас это символ ? ), то выдается соответствующее сообщение и операция не производится.

Следует заметить, что, как и положено по правилам Pascal , в интерфейсную часть модуля формы автоматически средой Delphi были добавлены заголовки процедур – обработчиков событий нажатий на клавиши:

procedure btn_sumClick(Sender: TObject);

procedure btn_ClearClick(Sender: TObject);

procedure btn_subClick(Sender: TObject);

procedure btn_rezClick(Sender: TObject);

На этом можно закончить программную реализацию задачи создания простейшего калькулятора, осуществляющего операции сложения и вычитания вещественных чисел. Отметим также, что наше приложение на 99% защищено от ошибок, связанных с операциями над некорректными исходными данными (а почему не 100% ?).

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

Создание папки

Создать папку в Delphi можно воспользовавшись функцией CreateDir или процедурой MkDir . Так же можно воспользоваться функцией ForceDirectories. Первые две команды корректно выполняют создание одной новой папки. Отличия же в том, как они себя ведут в случае если создать папку невозможно.

ForceDirectories(ExtractFilePath(Application.ExeName) + "/folder1/folder2/newfolder" );

Удаление папки

При удалении папки, важно учитывать есть ли в ней вложения или нет. Если папка пуста, то используется функция RemoveDir , в которой аналогично созданию, указывается путь к удаляемой папке. Функция при своем выполнении так же возвращает True, если удаление успешно и False, если удалить не удалось.

if RemoveDir("myfolder" ) then
ShowMessage("Папка успешно удалена." )
else
ShowMessage("Ошибка: папка не удалена." );

Если же папка не пуста, то можно использовать пользовательскую функцию, которая будет последовательно удалять все вложенные файлы, а затем и пустые папки. Для среды Delphi 2010, можно воспользоваться следующим методом:

TDirectory.Delete("myfolder" , True);

При этом, в разделе описаний должна быть добавлена библиотека IOUtils.

uses IOUtils;

Если же такой возможности нет, стоит использовать следующую функцию, описанную еще в DelphiWorld. В параметре указывается путь к удаляемой папке. При успешном удалении (включая все вложения), функция вернет значение True, если удаление не удалось, вернет False.

// Функция удаления директории с вложениями.
function MyDirectoryDelete(dir: string): Boolean;
var
fos: TSHFileOpStruct;
begin
ZeroMemory(@fos, SizeOf(fos));
with fos do begin
wFunc:= FO_DELETE;
fFlags:= FOF_SILENT or FOF_NOCONFIRMATION
pFrom:= PChar(dir + #0);
end ;
Result:= (0 = ShFileOperation(fos));
end ;

// Вызов функции удаление в программе.
begin if MyDirectoryDelete("myfolder" ) then
ShowMessage("Папка успешно удалена." )
else
ShowMessage("Ошибка: папка не удалена." );
end ;

В раздел описаний здесь необходимо добавить библиотеку ShellApi.

uses
ShellApi;

Проверка существования директории

Для проверки наличия директории используется функция DirectoryExists . В параметре так же указывается полный или относительный путь к папке. Если заданная папка существует, функция вернет True, в обратном случае False.

if DirectoryExists("myfolder" ) then
ShowMessage("Папка существует." )
else
ShowMessage("Такой папки нет." );

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

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

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

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

Дельфи имеет открытую архитектуру - это значит, что каждый программист волен усовершенствовать эту среду разработки, как он захочет. К стандартным наборам компонентов, которые поставляются вместе с Дельфи можно создать еще массу своих интересных компонентов, которые заметно упростят вам жизнь (это я вам гарантирую). А еще можно зайти на какой-нибудь крутой сайт о Дельфи и там скачать кучу крутых компонентов, и на их основе сделать какую-нибудь крутую прогу. Так же компоненты освобождают вас от написания "тысячи тонн словесной руды". Пример: вы создали компонент - кнопку, при щелчке на которую данные из Memo сохранятся во временный файл. Теперь как только вам понадобится эта функция вы просто ставите этот компонент на форму и наслаждаетесь результатом. И не надо будет каждый раз прописывать это, для ваших новых программ - просто воспользуйтесь компонентом.

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

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

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

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

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

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

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

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

Невизуальные компоненты видны только во время разработки приложения (Design-Time), а во время работы приложения (Run-Time) их не видно, но они могут выполнять какую-нибудь работу. Наиболее часто используемый невизуальный компонент - это Timer.

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

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

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

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

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

    В основном меню выберите Component -> New Component...

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

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

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

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

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

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

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

unit CountBtn;

Uses

StdCtrls;

Type
TCountBtn = class(TButton)

private
{ Private declarations }

protected
{ Protected declarations }

public
{ Public declarations }

published
{ Published declarations }

Procedure Register;

Implementation

Procedure Register;
begin
RegisterComponents("MyComponents", );
end;

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

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

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

FCount:integer;

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

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

procedure Click; override;

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

В директиве Public описываются те процедуры и функции компонента, которые будут доступны пользователю. (Например, в процессе написания кода вы пишите имя компонента, ставите точку и перед вами список доступных функций, объявленных в диретиве Public). Для нашего компонента, чтобы показать принцип использования этой директивы создадим функцию - ShowCount, которая покажет сообщение, уведомляя пользователя сколько раз он уже нажал на кнопку. Для этого в директиве Public напишем такой код:

procedure ShowCount;

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

constructor Create(aowner:Tcomponent);override; //Конструктор
//Свойство 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

end;

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

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

unit CountBtn;

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;

end;

Procedure Register;

Implementation

Procedure Register;
begin

end;


begin
inherited create(Aowner);
end;

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


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

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

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

Если вы сумели написать и понять, все то что здесь предложено, то установка компонента не должна вызвать у вас никаких проблем. Все здесь делается очень просто. В главном меню выберите пункт Component -> Install Component. перед вами открылось диалоговое окно Install Component. В нем вы увидите две закладки: Into exsisting Package и Into new Package. Вам предоставляется выбор установить ваш компонент в уже существующий пакет или в новый пакет соответственно. Мы выберем в уже существующий пакет.

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

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

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

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

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

Теперь мы попробуем создать свойство нестандартного типа. Рассмотрим это на примере метки - TLabel. У этого компонента есть такое свойство: Alignment. Оно может принимать следующие значения: taLeftJustify, taCenter, taRightJustify. Приступаем к созданию свойства. Ничего интересного мне придумать не удалось, но тем не менее я вам покажу это на примере того свойства, которое я придумал. Оно очень простое и поможет вам разобраться. Свойство будет называться ShowType (тип TShowTp), в нашем компоненте оно будет отвечать за отображение свойства Count. Если пользователь установит свойство ShowType в Normal, то кнопка будет работать, как и работала. А если пользователь присвоит этому свойтсву значение CountToCaption, то количество кликов, будет отображаться на самой кнопке.

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

type
TCountBtn = class(TButton)

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

TShowTp = (Normal, CountToCaption);

TCountBtn = class(TButton)

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

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

FShowType:TShowTp;

Мы создали поле 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;


end;

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

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

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

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

unit CountBtn;

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

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;

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

unit CountBtn;

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

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

Private
{ Private declarations }

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;

Implementation

Procedure Register;
begin
RegisterComponents("Mihan Components", );
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). Теперь в пакете уже нет вашего компонента. Затем проделайте стандартную процедуру по установке компонента.

Удачи в программировании...

(С) Авторские права принадлежат Михаилу Христосенко! При размещении на других сайтах указание имени автора и адреса сайта (http://delphid.dax.ru) обязательно!

Перед созданием своего компонента нужно выбрать для него предка. Кто же может быть предком для вашего компонента? Как правило, используются в виде предков TComponent, TControl, TWinControl, TGraphicControl, TCustomXXXXXX, а также все компоненты палитры компонентов. Возьмем для примера компонент TOpenDialog, который находится на странице Dialogs палитры компонентов. Он хорошо справляется со своей задачей, но у него есть одно маленькое неудобство. Каждый раз, когда его используешь необходимо каждый раз изменять значение свойства Options. И причем это, как правило, одни и те же действия.

Code:

OpenDialog1.Options:= OpenDialog1.Options + ;

чтобы файл, который мы пытаемся открыть с помощью этого диалогового окна, действительно существовал на диске.
Задание для себя мы уже выбрали, осталось за малым - создать компонент. Заготовку для компонента создаем, выбирая из меню команду Component/New Component... и в диалоговом окне выбираем
Ancestor type: TOpenDialog
Class Name: TOurOpenDialog
Palette Page: Our Test
Нажали Ok и у нас появился шаблон нашего будущего компонента. Переопределяем конструктор у этого компонента, т.е. в секции public вставляем строку:

Code:

нажатие на этой строке Ctrl + Shift + C создает шаблон для этого метода, внутри которого мы вставляем такие строки:

Обратите внимание: Комбинации клавиш Ctrl + Shift + стрелки вверх/вниз позволяют перемещаться между объявлением метода и его реализацией. Установка созданного компонента Component/Install Component...
Install Into New Package
Package file name: C:\Program Files\Borland\Delphi4\Lib\OurTest.dpk
Package description: Our tested package Вам не нравится, что у нашего компонента иконка такая же как у стандартного? Тогда создадим для него свою собственную. Для этого нам необходимо вызвать Tools/Image Editor. Создаем новый *.dcr файл.
Вставляем в него рисунок Resource/New/Bitmap. Устанавливаем размер картинки 24x24 точек. А дальше - ваше творчество... Обратите внимание: цвет точек, совпадающий с цветом точки в левом нижнем углу рисунка, будет считаться ПРОЗРАЧНЫМ! После того как вы создали свой рисунок, переименуйте его из Bitmap1 в TOurOpenDialog и сохраните файл с именем OurOpenDialog.dcr. Удалите компонент из пакета и установите его снова (только в этом случае добавится и ссылка на *.dcr файл). Compile, Install и удачи!

{======================================================}

unit OurOpenDialog;

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

TOurOpenDialog = class(TOpenDialog)

{ Private declarations }

{ Protected declarations }

{ Public declarations }

constructor Create(AOwner: TComponent); override;

{ Published declarations }

procedure register;

procedure register;

RegisterComponents("Samples", );

{ TOurOpenDialog }

constructor TOurOpenDialog.Create(AOwner: TComponent);

inherited Create(AOwner); {Вызываем

унаследованный конструктор}

Options:= Options + ;

{Выполняем необходимые нам действия}

Объявление компонента состоит из секций, таких как private , protected , public и published . Что они означают?
Это директивы видимости. Все что объявлено в секции private , доступно только внутри модуля в котором объявлен класс (приватные объявления). Здесь как правило объявляются переменные, в которых хранятся значения свойств, а также методы (процедуры или функции) доступа к ним. Все что объявлено в секции protected , доступно как и в секции private, а также наследникам данного класса (интерфейс разработчика). Здесь можно объявить методы доступа к значениям свойств (если вы хотите позволить изменять эти методы потомкам вашего компенента),
а также свойства, методы и события (методы реакции на события) в компонентах типа TCustomXXX.
Все что объявлено в секции public , доступно любому пользователю компонента (интерфейс этапа выполнения).
Здесь объявляются, как правило методы. В секции published можно объявлять только свойства и события (они объявляются в виде свойств). Они доступны во время проектирования приложения (интерфейс этапа проектирования).

Свойства

Свойства типа масив - обычные массива Object Pascal, но в отличии от последних могут индексироваться не только числовыми значениями но и строковыми. К сожалению этот тип свойства требует пользовательского редактора свойств (в инспекторе объектов редактор свойства имеет кнопку с тремя точками [...]), по-этому в указанном ниже примере свойство ArrayProp объявлено в секции public.

TOurComponent = class(TComponent)

{ Private declarations }

FArrayProp: array of integer;

function GetArrayProp(aIndex: integer): integer;

procedure SetArrayProp(aIndex: integer; const

Value: integer);

{ Protected declarations }

{ Public declarations }

property ArrayProp: integer read

write SetArrayProp;

{ Published declarations }

Спецификаторы свойств

Спецификатор default указывает сохранять значение свойства в файле формы или нет . Если значение свойства совпадает со значением default - значение в файле формы не сохраняется , если значения не равны - сохраняется . Это можно проверить , положив компонент на форму и выбрать правой кнопкой мыши пункт меню "View as Text". Default не устанавливает первоначальное значение свойства к указанному . Это необходимо сделать в конструкторе компонента .

Code:

unit OurComponent;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls;

type

TOurComponent = class (TComponent)

private

{ Private declarations }

FMyInteger: Integer;

protected

{ Protected declarations }

public

{ Public declarations }

constructor Create(AOwner: TComponent); override ;

published

{ Published declarations }

property MyInteger: Integer read FMyInteger

write FMyInteger default 10 ;

end ;

implementation

constructor TOurComponent.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FInteger:= 10 ;

end ;

end .

Спецификатор nodefault отменяет заданное по умолчанию значение свойства. Этот спецификатор, как правило, используется для отмены заданого по умолчанию значения унаследованного свойства.

Например:

Code:

property AutoSize nodefault ;

Спецификатор stored указывает когда сохранять в файле формы значение свойства. После stored может стоять true (всегда сохранять), false (никогда не сохранять) или название функции, которая возвращает логический результат.

Code:

property OneProp: integer read FOneProp

write

SetOneProp

stored False;

property TwoProp: integer read FTwoProp

write

SetTwoProp

stored True;

property ThreeProp: integer read FThreeProp

write SetThreeProp

stored Fuct;

Форма "О программе" используется в качестве информативных целей. Чаще всего в ней пишется наименование программы, назначение, авторы и лицензионное соглашение. Чаще всего размещается в главном меню в пункте Помощь->О программе....

Для создание формы "О программе" в Delphi (Делфи, Дельфи) нужно создать обычную форму, как на рисунке ниже:

Для создания любой формы в Delphi 7 используем следующую команду из меню File->New->Form, а при разработке проекта в более новой среде, к примеру Delphi XE2, нужно использовать немного другую команду: File->New->VCL Form - Delphi.

После создания формы нужно выставить нужные размеры и рекомендуется выполнить следующие настройки:

  • Выставить свойство Position. По умолчанию здесь указано значение poDesigned, которое диктует открываемой форме появляться там, где она находилась в момент создания программы. Поэтому нужно выставить, так чтобы форма появлялась по центру относительно формы, из которой она была вызвана. Для этого в свойство Position надо выставить значение poOwnerFormCenter.
  • Также можно отключить свойство AutoScroll, чтобы не появлялись полосы прокрутки.
  • Так как в форме будет краткая статическая информация, то иметь возможность изменять размеры формы во время выполнения нет никакой необходимости. Поэтому в свойстве BorderStyle выставить значение bsSingle.
  • Еще нужно настроить вложенные свойства в BorderIcons. Нужно в свойствах biMinimize и biMaximize выставить значения в false, что не позволит минимизировать и развернуть форму соответственно.

Помимо всех описанных настроек, также можно украсить форму фоном. Для этого нужно из палитры компонентов поместить Image, который находится во вкладке Additional, если вы пишите в Delphi 7. В свойстве сразу нужно выставить значение alClient, которое растянет контейнер для изображения на всю форму.

Также при использовании TLabel можно выставить Transparent в true. Данная опция сделает так, чтобы фон метки был прозрачен, что будет выглядеть намного красивее, если используется вспомогательный фон.

Заключение

На этом думаю статью закончить. Данный материал будет полезен для начинающих Delphi программистов или просто, кому интересно писать программы. При возникновении трудностей пишите в комментариях, и я как-только смогу подскажу по форме "О программе" в Делфи. Также я в архиве выложил тестовый проект с данной формой и ее вызовом из другой формы.



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows