Створення компонента у делфі приклад. Динамічне створення компонентів у Delphi. Приклад динамічного створення форми

Професійна розробка програм за допомогою Delphi 5 | Засоби розробки Комп'ютерПрес 2"2001

створення компонентів Delphi

Введення у створення компонентів Delphi

При розробці програм за допомогою Borland Delphi створювати компоненти зручно з наступних причин:

  1. Простота використання. Компонент міститься на форму, і для нього необхідно встановлювати значення властивостей та писати код обробників подій. Тому якщо у проекті якесь поєднання елементів управління та обробників пов'язаних з ними подій зустрічається у двох місцях, то є сенс подумати про створення відповідного компонента. Якщо ж поєднання елементів управління та обробників пов'язаних з ними подій зустрічається більше двох разів, створення компонента гарантовано заощадить зусилля при розробці програми.
  2. Проста організація групової розробки проекту. Під час групової розробки окремі частини проекту можна визначити як компоненти та доручити цю роботу різним програмістам. Компоненти можна налагодити окремо від програми, що зробити досить легко.
  3. Простий і ефективний спосібобмін кодом з іншими програмістами.Є чимало сайтів, наприклад http://www.torry.net/ , де можна знайти компоненти, що вільно розповсюджуються, або придбати їх за символічну плату.

Пакети компонентів

У Delphi компоненти зберігаються у пакетах (packages). Список пакетів компонентів, що використовуються, можна викликати за допомогою пункту меню Component/Install Packages (правда, цей діалог чомусь має заголовок Project Options).

За допомогою цього діалогу можна додати новий пакет(Add), видалити наявний (Remove). Видалення означає не фізичне видалення файлу з диска, а видалення посилання серед розробки на даний пакет. При додаванні нового пакета компоненти, що зберігаються в ньому, з'являються на палітрі, а при видаленні навпаки зникають. Пакет можна не видаляти, а "сховати" його вміст на етапі розробки за допомогою зняття позначки навпроти імені пакета у списку. Можна також переглянути компоненти та їх піктограми (Components). І нарешті, можна відредагувати додані користувачем пакети (Edit) - пакети, що поставляються разом з Delphi, не можна редагувати (кнопка Edit недоступна).

В даному діалозі можна вказати, як створювати проект: з використанням runtime-пакетів або без них. Звідси ясно, що пакети компонентів бувають двох типів: runtime package (пакет, що працює під час виконання) та design-time package (пакет, що використовується під час розробки). Усі вони є DLL (динамічно завантажувані бібліотеки).

Runtime-пакети (розширення *.bpl) поставляються кінцевому користувачеві разом із проектом, якщо проект був скомпільований з включеною опцією Build with runtime packages. Сама програма (*.exe або *.dll) у цьому випадку виходить невеликою, але разом з ним треба передавати досить об'ємні *.bpl-файли. Згідно з оцінками фахівців постачання проекту з runtime-пакетами дає перевагу в обсязі файлів, що поставляються, якщо тільки він включає п'ять або більше модулів (*.exe або *.dll), написаних на Delphi. При спільній роботі цих модулів досягається економія ресурсів операційної системи, оскільки один завантажений в ОЗП пакет обслуговує кілька модулів.

Design-time-пакети (розширення *.dcp) використовуються лише на етапі розробки. Під час розробки вони підтримують створення компонентів формі. Комплексований проект Delphi включає код не з пакета компонентів, а з *.dcu-файлів. Хоча *.dcp-файл генерується з *.dcu-файлу, їх вміст може не збігатися, якщо *.pas-файл були внесені зміни і пакет не був перекомпільований. Компіляція можлива лише для пакетів, створених програмістами. Це досягається натисканням кнопки Edit у вищезгаданому діалозі. Після цього з'являється форма, що дозволяє проводити маніпуляції із пакетом.

Пакет містить дві секції. У секції Contains наведено список модулів, що формують компоненти даного пакета (*.pas- та *.dcu-файли) та їх піктограми (*.dcr-файли). Секція Required містить посилання інші пакети, необхідних роботи цих компонентів. Додавання нового компонента до пакета виконується кнопкою Add, видалення наявного – кнопкою Remove. Доки пакет не буде скомпілюваний натисканням кнопки Compile, всі зміни, які вносяться до пакета, не з'являться в середовищі розробки. І нарешті, команда Install доступна в тому випадку, коли вміст пакета видалено з середовища розробки за допомогою зняття позначки напроти імені пакета в попередньому діалозі.

Команда Option дозволяє вибрати для компіляції пакета опції, аналогічні до опцій проекту. Вони можна визначити тип даного пакета: працюючий під час виконання, працюючий під час розробки, або той і інший одночасно (тип пакета за замовчуванням). В опціях визначаються каталоги, у яких слід шукати необхідні модуліта зберігати результати компіляції. Вони також визначаються дії, необхідних налагодження: перевіряти чи ні діапазон допустимих значень, як здійснювати оптимізацію, як обробляти помилки вводу-вывода. І нарешті, до опції може бути включена інформація про версію пакета. Це дуже важливо, якщо програма розповсюджується разом з runtime-пакетами: при роботі програми установки інформація про версію дозволить коректно замінити застарілі версії пакетів, і навпаки, при спробі інсталювати пакет більш ранньої версії, ніж наявний на даному комп'ютері, останній не буде перезаписаний.

Шаблони компонентів

Delphi дозволяє створювати найпростіші складові компоненти із кількох звичайних компонентів, вибраних на формі під час розробки. Відповідний експерт викликається за допомогою пункту меню Components/Create Component Template. Цей пункт меню доступний, якщо на формі виділено хоча б один компонент. Після вибору з'являється діалогова панель Component Template Information.

У цьому діалозі слід вказати ім'я класу та ім'я сторінки на панелі компонентів, куди слід помістити новий компонент. Якщо сторінка з цим ім'ям відсутня на панелі компонентів, вона буде створена. Можна також змінити запропоновану піктограму нового компонента, завантаживши відповідний *.bmp-файл.

Під час створення шаблону запам'ятовуються як властивості, змінені програмістом в інспекторі об'єктів, і обробники подій, пов'язані з виділеними елементами управління. При цьому обробники подій запам'ятовуються повністю, без фільтрації звернень до інших (не виділених на формі) компонентів, глобальних змінних методів і т.д. Відповідно, якщо в іншому проекті таких компонентів (змінних, методів) немає, то при спробі скомпілювати такий проект буде отримано діагностичне повідомлення Unknown Identifier.

Коли потрібно користуватися шаблонами? Насамперед, у випадках, коли необхідно змінити будь-які властивості, які є за умовчанням у базовому класі. Наприклад, у будь-якій програмі використовується елемент керування для редагування рядка жовтого кольору. Можна помістити компонент TEdit на форму, змінити властивість Color на жовтий, відзначити цей компонент і зберегти як шаблон. Після цього можна звертатися до цього шаблону, і поміщений на форму компонент матиме жовтий колір. Однак не варто зловживати цією можливістю, адже для елемента управління зі зміненим кольором буде створено новий клас і в пам'яті будуть розмножені всі віртуальні методи. Це негативно позначиться ресурсах операційної системи.

Використовувати шаблони компонентів зручно також, коли необхідно перенести ряд компонентів разом із обробниками подій із однієї форми на іншу. Для цього всі вони виділяються, створюється шаблон компонентів, який і міститься на нову форму. При цьому будуть перенесені не лише самі компоненти, а й обробники подій, чого не можна досягти при виклику команд Copy/Paste – в останньому випадку обробники подій будуть втрачені.

Компоненти, які створюються за допомогою команди Create Component Template, суттєво відрізняються від звичайних компонентів, які створюються стандартним способом (описаним нижче). Візуально головна відмінність полягає в наступному: якщо шаблон включає кілька елементів управління, то, після того як такий компонент поміщений на форму, можна виділити окремий елементуправління та видалити його – при цьому інші збережуться на формі. Для стандартних компонентів, якщо вони включають кілька елементів управління, неможливо виділити один з них і видалити -компонент виділяється і видаляється повністю.

Створення найпростішого компонента

При написанні нового компонента необхідно ясно уявляти, що компонент створюється для програмістів, а чи не для кінцевих користувачів. При цьому бажано, щоб програміст не вникав в деталі реалізації компонента, а просто користувався властивостями і подіями, що експонуються ним. Це досягається дуже ретельним тестуванням. Новий компонент необхідно тестувати навіть у ситуаціях, для роботи в яких він не призначений.

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

Створення компонента починається з вибору пункту меню Component/New components. Після цього відразу з'являється діалог New Component.

У цьому діалозі необхідно визначити клас-предок, ім'я новоствореного класу, сторінку на палітрі, куди буде розміщено новий компонент, ім'я модуля, що містить реалізацію нового компонента, і шлях до нього. Якщо новий компонент використовує інші модулі, шлях до яких не описаний, їх необхідно визначити в полі Search Path.

Отже, перше (і, мабуть, головне) завдання – вибір класу-предка. У списку, що випадає, як клас-предок пропонуються всі компоненти, наявні на палітрі, у тому числі й ті, які не входять до стандартної поставки Delphi. Необхідно як клас-предок вибрати клас, який максимально наближений за властивостями до створюваному класу. Для нашого завдання можна, наприклад, вибрати як предок TWinControl, але в цьому випадку нам потрібно буде реалізовувати всі візуальні ефекти натискання кнопки і т.д. Тому ми вибираємо як предок TButton.

Ім'я новоствореного класу має відображати зміст компонента і в жодному разі не збігатися з ім'ям вже зареєстрованого компонента! На етапі заповнення даного діалогу імена на збіги не перевіряються – пригоди, пов'язані з такою помилкою, розпочнуться пізніше…

При виборі сторінки необхідно знати, що якщо задати ім'я неіснуючої сторінки, то буде створено нову.

І нарешті, при натисканні як кнопки Install, так і кнопки OK буде створена заготовка для реалізації нового компонента. Однак при натисканні кнопки Install заготівля буде поміщена на палітру компонентів, а при натисканні кнопки OK просто створена. Рекомендовано користуватися кнопкою Install. Після того, як компонент буде інстальований, його можна помістити на форму. Тепер усі зміни, що вносяться до коду реалізації компонента, будуть компілюватися разом із проектом, і програміст відразу ж отримуватиме повідомлення про помилки. Якщо компонент не інсталювати, для пошуку помилок його необхідно компілювати через редактор пакетів (див. вище) натисканням кнопки Compile, що менш зручно.

Отже, після натискання кнопки Install з'являється ще один діалог, який дозволяє визначити пакет, куди буде розміщений цей компонент.

У цьому діалозі є дві сторінки, на першій з них можна вибрати один із існуючих пакетів, а на другій створити новий. Дуже бажано давати короткий текстовий опис пакета, саме він показуватиметься в діалозі, що викликається за командою Component/Install packages (див. вище). Після вибору пакета та натискання клавіші OK викликається редактор пакета, куди автоматично розміщується новостворений модуль реалізації нового компонента. Корисно не закривати його, а зрушити в один із кутів екрана, щоб він міг бути активований натисканням клавіші миші.

Одночасно в редакторі коду буде створено «заготівлю» для опису нового компонента:

Unit ButtonBeep; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TButtonBeep = class(TButton) private (Private declarations) protected (Protected declarations) public (Public declarations) published (Published declarations) end; procedure Register; implementation procedure Register; begin RegisterComponents("Samples", ); end; end.

У найновішому класі оголошено чотири секції, значення яких детально описано в розділі «Область видимості змінних та методів» попередньої статті цього циклу (Комп'ютерПрес № 1"2001). Крім того, у новому класі визначено процедуру Register, яка викликається середовищем розробки Delphi при інсталяції даного модуля як компонента. Вона містить ім'я сторінки на палітрі, куди поміщається даний компонент, і в квадратних дужках – ім'я класу. один від одного комою, наприклад:

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

Продовжимо вирішення поставленого завдання – створення кнопки, яка видає писк. Вчинимо спочатку тривіально (але як з'ясується потім, неправильно) – призначимо обробник події OnClickу конструкторі кнопки. Для цього в секції private визначимо заголовок нового методу BtClick (Sender: TObject) і реалізуємо його в секції реалізації:

Procedure TButtonBeep.BtClick(Sender:TObject); begin Beep; end;

конструктор Create(AOwner:TComponent); override;

з обов'язковою директивою override! Реалізуємо його у секції реалізації:

Constructor TButtonBeep.Create(AOwner:TComponent); begin inherited Create(AOwner);

OnClick:=BtClick; end;

Після цього скомпілюємо компонент. Поставимо зі сторінки Samples кнопку на форму та запустимо проект на виконання. Можна переконатися, що кнопка при натисканні пищить!

Тепер знову перейдемо у середу розробки та призначимо обробник події OnClick в інспекторі об'єктів. В обробнику події виведемо текст у заголовок форми:

Procedure TForm1.ButtonBeep1Click(Sender:TObject); begin Caption:="Test"; end;

Таким чином, при написанні нових компонентів завжди слід враховувати можливість зміни властивостей та обробників подій за допомогою інспектора об'єктів. Якщо будь-яка властивість (подія) не повинна змінюватися, її не слід відображати в інспекторі об'єктів. А якщо воно вже відображається, його слід приховати (про це ми поговоримо пізніше). Програміст має повне право змінити будь-які властивості в інспекторі об'єктів, і якщо після цього компонент перестає працювати, у цьому винен розробник компонента, але в жодному разі не програміст, який його використовує.

Як же коректно вирішити дане завдання? Один із способів створення компонентів - переписування вже існуючих методів. Під час розгляду файлу StdCtrls.pas, де реалізовані вихідні коди для компонента TButton, можна зазначити у ньому наявність динамічного методу Click, який можна переписати. Тому знову повертаємося до вихідного коду, створеного експертом Delphi під час створення компонента (прибираємо конструктор і метод BtClick). Потім у секції public визначаємо заголовок методу:

Procedure Click; override;

та наводимо реалізацію методу:

Procedure TButtonBeep.Click; begin inherited Click;

beep; end;

Можна переконатися, що при натисканні кнопка видає писк. Крім того, при призначенні оброблювача подій в інспекторі об'єктів цей оброблювач виконується і писку не зникає! Компонент реалізовано коректно.

  1. На даному прикладі корисно проаналізувати можливі помилки під час написання коду:
  2. Забута директива override щодо заголовка методу Click. Кнопка перестає їсти, отже, метод Click не викликається.

Забутий виклик методу предка (inherited Click) у реалізації процедури Click. Кнопка продовжує їсти при натисканні, але код у призначеному в інспекторі об'єктів обробнику подій не виконується. Отже, метод Click класу TButton викликає подію OnClick. Тепер поміняємо піктограму компонента TButtonBeep на панелі. За замовчуванням для нового компонента використовується піктограма предка. Для цього викличемо редактор Image Editor командою Tools/Image Editor. У редакторі викличемо команду File/New/Component Resource File (*.dcr). Після команди Resource / New / Bitmap з'явиться діалог, в якому пропонується розмір піктограми 32х32. Ці розміри за промовчанням слід змінити на 24х24 – такий розмір повинні мати піктограми компонентів! Після натискання кнопки OK слід намалювати будь-яке зображення за допомогоюстандартних інструментів , схожих на інструменти. Пам'ятайте, що колір лівого нижнього пікселя є кольором маски – цей колір буде прозорим.

Після цього необхідно перевизначити ім'я ресурсу з піктограмою за промовчанням його ім'я - Bitmap1. Нове ім'я ресурсу має збігатися з ім'ям класу – у разі TButtonBeep.

Тепер необхідно зберегти файл з піктограмою в тому самому каталозі, де знаходиться модуль, що містить процедуру Register для даного компонента, і з тим самим ім'ям, що і ім'я модуля. Тільки розширення у файлу буде не *.pas, а *.dcr. Файл з піктограмою компонент готовий. Однак якщо ми подивимося на палітру компонентів, то побачимо, що там зберігається стара піктограма. Якщо перезавантажити Delphi або навіть операційну систему, стара піктограма, як і раніше, залишиться на панелі. Щоб змінити піктограму, необхідна повторна реєстрація компонента. Для цього необхідно:

Цей приклад слід розглядати як тестову вправу. Перед написанням нового компонента необхідно подивитися, чи існують аналогічні серед компонентів, що вільно розповсюджуються. Є практично будь-які кнопки: прозорі, тікають, круглі, кольорові і т.д. Приблизно так само з іншими компонентами – нащадками одного класу. Тому найчастіше доводиться реалізовувати компоненти, які з кількох елементів управління.

Таким чином, у цьому прикладі ми вивчили застосування переписування методів для створення нових компонентів.

Створення складного компонента

Припустимо, у додатку необхідно запровадити список прізвищ клієнтів. У тому самому додатку знадобиться введення списку телефонів. Введення списку досить поширена операція, тому слід подумати про реалізацію його у вигляді компонента.

Для введення нового елемента до списку буде потрібно редактор – компонент TEdit. Далі користувач повинен мати можливість переглянути список - знадобиться компонент TListBox. Крім того, будуть потрібні команди для занесення поточного значення з TEdit до списку, редагування вибраного елемента списку та його видалення. Найпростіше ці команди реалізувати за допомогою кнопок. Для спрощення завдання помістимо форму одну кнопку, при натисканні якої будемо додавати вміст компонента TEdit в список.

Отже, ми повинні створити новий компонент, який включав би TEdit, TListBox і TButton. Як завжди, почнемо його створення з команди Component/New Component. Після цього з'являється діалог, де слід визначити клас-предок, ім'я класу, ім'я модуля. З ім'ям класу та ім'ям модуля жодних складнощів не виникає, а ось ім'я класу-предка неясно. У нас є три елементи керування. Загальним класом-предком для них є TWinControl. Але якщо в якості класу-предка вибрати його, на нас чекає дуже тривала та стомлива реалізація коду TButton, TEdit та TListBox. У таких випадках необхідно як клас-предок вибирати компонент, здатний бути «татом» по відношенню до інших компонентів. Серед стандартних компонентів, що розповсюджуються разом із Delphi, таких три: TPanel, TGroupBox, TScrollBox. Виберемо як клас предка панель, але не сам компонент TPanel, а клас TCustomPanel. Переваги вибору TCustomPanel перед TPanel ми обговоримо нижче.

Назвемо новий клас ім'ям TListAdd і натисніть кнопку Install. Після вибору пакета компонент буде встановлений на палітру, звідки його можна помістити на форму новоствореної програми. Це зручно, оскільки при компіляції проекту модуль компонента також компілюватиметься і за наявності помилок компілятор видасть повідомлення.

Було б зручно помістити наші елементи управління на будь-яку форму і потім створити компонент. У стандартному постачанні Delphi такий експерт відсутній. Тому необхідно буде створювати компоненти самим та розміщувати їх на панелі. Створення елементів управління - TButton, TEdit і TListBox - розумно виконати в конструкторі TCustomPanel, для чого, очевидно, необхідно його переписати. Розмістимо поки що елементи управління в квадраті 100х100. Координати їх також необхідно визначати у конструкторі. При цьому слід мати на увазі, що після відпрацювання конструктора будь-якого елемента управління він ще не має батька, тобто не знає щодо якого вікна йому треба відраховувати координати лівого верхнього кута. Спроба змінити координати дочірнього вікна, у якого немає батька, негайно призведе до генерації винятку. Тому першим оператором після виклику конструктора елемента управління буде призначення йому батька, як виберемо TCustomPanel. Її ж зробимо та його власником, у разі не знадобиться переписувати деструктор.

Отже, в секції uses додаємо модуль StdCtrls, де є описи класів TEdit, TButton і TListBox, а в секції private визначаємо три змінні:

Private FEdit: TEdit;

FListBox: TListBox;

FButton:TButton;

У секції public оголошуємо заголовок конструктора з обов'язковою директивою override:

Constructor Create(AOwner:TComponent); override;

Реалізуємо конструктор у секції реалізації: Constructor TListAdd.Create(AOwner:TComponent); begin inherited Create(AOwner); FButton:=TButton.Create(Self);

FButton.Parent:=Self;

FButton.Left:=5;

FButton.Top:=5;

FButton.Width: = 40;

FButton.Height:=25;

FEdit:=TEdit.Create(Self);

FEdit.Parent:=Self;

FEdit.Left:=50;<100 then Width:=100; if Height<100 then Height:=100; FEdit.Width:=Width-55; FListBox.Width:=Width-10; FListBox.Height:=Height-40; end;

Перший оператор – виклик обробника WM_SIZE за умовчанням (inherited). Після його виклику у властивостях Width та Height будуть знаходитись нова ширина та висота панелі. Після цього визначаються мінімальні розміри компонента, в даному випадку – 100х100. Якщо розмір по горизонталі або вертикалі менший за мінімальний, то йому присвоюється мінімальне значення. Потім відбувається масштабування елементів керування так, щоб вони заповнювали всю панель із невеликими відступами. Скомпілювавши компонент через редактор пакетів, можна вже на етапі розробки відзначити коректну поведінку елементів управління на панелі при масштабуванні, а також те, що розмір компонента не можна зробити менш ніж 100х100.

Тепер корисно запустити весь проект на виконання, спробувати вводити дані в однорядковий редактор тексту та натискати кнопку. При цьому нічого до списку не додається. І не дивно, що ніде у нашому компоненті не вказано, що треба робити при натисканні кнопки. Для того, щоб зробити обробник події, пов'язаної з натисканням кнопки, можна вчинити, як при написанні компонента TbuttonBeep, тобто визначити новий клас - нащадок TButton і переписати метод Click. Проте визначення нового класу потребує системних ресурсів (розмножуються віртуальні методи). Якщо ми відзначимо компонент на формі та подивимося на інспектор об'єктів, то виявимо, що компонент TlistAdd експонує небагато властивостей та жодної події, у тому числі жодного обробника події кнопки OnClick. Тому те, що в минулому розділі ми відкинули як неправильний метод - перевизначення обробника кнопки OnClick в даному випадку застосовно, оскільки програміст не може в інспекторі об'єктів призначити новий обробник. Отже, у секції private описуємо заголовок нового методу:

Procedure BtClick(Sender:TObject);

У реалізації конструктора TListAdd присвоюємо цей оброблювач обробнику подій FButton.OnClick:

FButton.OnClick:=BtClick;

І нарешті, реалізуємо метод BtClick:

Procedure TListAdd.BtClick(Sender:TObject); begin if length(FEdit.Text)>0 then begin FListBox.Items.Add(FEdit.Text);

Спочатку перевіримо, чи не порожній однорядковий редактор: ми не будемо додавати до списку порожні рядки. Потім переносимо вміст редактора до списку (FListBox.Items.Add(FEdit.Text);) і готуємо редактор до введення наступного значення – а саме, очищаємо його від тексту (який вже перенесено до списку) і переносимо фокус введення. Тепер після компіляції та запуску програми можна переконатися, що вона працює коректно – при натисканні кнопки вміст редактора переноситься до списку.

Додавання властивостей та методів

Якщо поруч із компонентом TListAdd помістити компонент TPanel і порівняти показуване в інспекторі об'єктів, можна відзначити, що з панелі експонується досить багато властивостей і подій, а TListAdd – лише кілька властивостей. Тим часом клас TCustomPanel є предком обох компонентів. Щоб зрозуміти причину, відкриємо модуль ExtCtrls.pas і розглянемо різницю між класами TCustomPanel і TPanel. Можна відзначити, що всі методи та змінні, які забезпечують функціональність панелі, визначені на рівні класу TCustomPanel. У ньому ж визначені властивості, які потім відображаються в інспекторі об'єктів для TPanel, тільки ці властивості визначені в секції Protected. Реалізація ж класу TPanel дуже проста: як предок визначається TCustomPanel, і властивості цього класу редекларуються, але вже в секції published. Стає зрозуміло, що необхідно зробити в класі TListAdd для появи в інспекторі об'єктів властивостей та методів класу TcustomPanel, а саме редекларувати властивості. У секції published класу TListAdd запишемо:

Property Align;

property OnMouseDown;

Тепер розглянемо, як можна запровадити нову властивість (те, що ми робили вище – редекларація наявних властивостей). Як відповідна властивість для відображення в інспекторі об'єктів можна використовувати текст на кнопці: нехай програміст, що користується компонентом TListAdd, самостійно змінює текст на етапі розробки. Спроба ввести нову властивість (назвемо її BtCaption) за допомогою оголошення:

Property BtCaption:string read FButton.Caption write FButton.Caption;

призводить до помилки під час спроби компіляції компонента. Тому визначимо заголовки двох методів у секції private:

Function GetBtCaption:string; procedure SetBtCaption(const Value:string);

У секції published оголосимо властивість BtCaption:

Property BtCaption:string read GetBtCaption write SetBtCaption;

І нарешті, реалізуємо два оголошені методи у секції реалізації:

Function TListAdd.GetBtCaption:string; begin Result:=FButton.Caption; end; procedure TListAdd.SetBtCaption(const Value:string); begin FButton.Caption:=Value; end;

Після компіляції компонента за допомогою редактора пакетів в інспекторі об'єктів з'являється нова властивість. Зміна значення цієї якості відбивається прямо на етапі розробки.

Тепер визначимо нову подію. У цьому завдання було б розумним створити подію, що дозволяє програмісту, використовує даний компонент, аналізувати текст перед занесенням вмісту редактора до списку і дозволити чи заборонити додавання тексту до списку. Отже, цей метод повинен як параметр містити поточне значення тексту в редакторі і залежати від логічної змінної, якій програміст може призначити значення True або False. Крім того, будь-який обробник події в компоненті зобов'язаний залежати від параметра Sender, в якому компонент, що викликає, передає посилання на самого себе. Це необхідно робити тому, що в середовищі розробки Delphi один і той же обробник події може викликатися з різних компонентів і програміст повинен мати можливість проаналізувати, який саме компонент викликав обробник. Отже, після слова type в розділі interface перед визначенням TListAdd визначаємо новий тип методу:

Type TFilterEvent=procedure(Sender:TObject; const EditText:string; var CanAdd:boolean) of object;

FOnFilter:TFilterEvent;

І в секції published визначаємо властивість даного типу:

Property OnFilter:TFilterEvent read FOnFilter write FOnFilter;

При визначенні нової якості посилаємось на змінну FOnFilter, а не на методи – вони тут не потрібні. Тепер, якщо компілювати компонент за допомогою редактора пакетів, можна виявити появу в інспекторі об'єктів події OnFilter. Однак якщо ми призначимо йому обробник і запустимо проект на виконання, він може не викликатися. Це тому, що ми ніде його викликали у нашому компоненті. Підходяще місце для виклику події OnFilter – обробник події OnClick для FButton, який вже реалізований. Тому ми змінимо код реалізації раніше визначеного методу BtClick:

Procedure TListAdd.BtClick(Sender:TObject); var CanAdd:boolean; begin if length(FEdit.Text)>0 then begin CanAdd:=True;

if Assigned(FOnFilter) then FOnFilter(Self,FEdit.Text,CanAdd);<>if CanAdd then begin FListBox.Items.Add(FEdit.Text);<>FEdit.Text:=""; FEdit.SetFocus; end else beep;

end; end;

Отже, у наведеному вище фрагмент коду визначається логічна змінна CanAdd. При написанні коду слід враховувати, що програміст може зробити обробник події OnFilter. Тому встановлюємо значення змінної CanAdd за промовчанням рівним True – усі рядки додавати до списку. Далі, перед викликом FonFilter, слід перевірити, чи зробив програміст обробник події. Це досягається викликом методу Assigned, який повертає логічне значення. Для вказівника виклик методу Assigned еквівалентний перевірці P<="Z"); end;

Код простий для розуміння, єдиним його нюансом є перевірка того, що текст є не пустим рядком, перед перевіркою першої літери тексту в обробнику події ListAdd2Filter. Проведення такої перевірки є обов'язковим: рядки в Object Pascal - це об'єкти, і порожньому рядку відповідає nil-покажчик. При спробі перевірити першу літеру порожнього рядка програма спробує дереференсувати nil, що призведе до виключення. В даному випадку це не страшно: перед викликом обробника подій FOnFilter із компоненту TListAdd перевіряється рядок на ненульову довжину. Однак для компонентів, вихідний текст яких недоступний, така перевірка є обов'язковою!

Приховування властивостей в інспекторі об'єктів

Припустимо, ви робите компонент доступу до даних, наприклад, нащадок класу TTable. Припустимо, у цьому компоненті аналізується список таблиць, наявних у базі даних, і за якими ознаками (наприклад, наявність поля певного типу і з певним ім'ям) вибирається одна для роботи. Для нормальної роботи компонента ім'я цієї таблиці повинне заноситися як TableName. Але це властивість відображається в інспекторі об'єктів! Програміст, який використовує цей компонент, може змінити його значення на етапі розробки, що припустимо, зробить компонент непрацездатним. І він має рацію! Якщо якісь із властивостей чи подій не можна змінювати, вони мають бути приховані.

Ми продовжимо роботу над компонентом TListAdd і як модельне завдання приберемо з інспектора об'єктів властивість Cursor. Ця властивість визначена в секції, published в класі TСontrol і відображається в інспекторі об'єктів для TListAdd з самого початку розробки компонента. Тому можна спробувати перевизначити дана властивістьу секції protected. Компілятор дозволить таке перевизначення, але до бажаного результату це не призведе: властивість Cursor як було, так і залишиться в інспекторі об'єктів... Будь-яка властивість, будучи певною в секції published, завжди відображатиметься в інспекторі об'єктів для всіх нащадків даного класу.

Для приховання властивості з інспектора об'єктів використовуємо дві можливості компілятора Delphi, а саме:

  1. При оголошенні нової властивості з ім'ям, що збігається з ім'ям вже наявної властивості, раніше певна властивість «затінюється».
  2. Властивості, які мають доступ тільки для читання або тільки для запису, не відображаються в інспекторі об'єктів, навіть якщо вони оголошені в секції публіковані.

Перед початком роботи з приховання якості Cursor корисно видалити компоненти TListAdd з форми, інакше може статися виняток під час читання ресурсу форми. Отже, в секції private оголошуємо змінну FDummy:integer (ім'я та тип змінної можуть бути будь-якими) і в секції published визначаємо нову властивість:

Property Cursor:integer read FDummy;

Нове якість має називатися Cursor, тип його повинен збігатися з типом змінної, певної вище, властивість має бути лише читання чи тільки запис. Після компіляції компонента за допомогою редактора пакетів слід знову помістити компонент TListAdd на форму. Можна виявити, що властивість Cursor не відображається в інспекторі об'єктів.

Тепер трохи ускладнимо завдання. Припустимо, необхідно, щоб курсор був показаний не у вигляді стрілки, а у вигляді пісочного годинника (crHourGlass). Щоб змінити значення властивостей за умовчанням, нове значення необхідно присвоїти змінної в конструкторі. При спробі в конструкторі надати нове значення Cursor

Cursor:=crHourGlass;

компілятор Delphi видасть діагностичне повідомлення у тому, що не можна призначити нове значення змінної, призначеної лише читання. Якщо створити нову властивість «тільки для запису», то компілятор видасть вже інше діагностичне повідомлення – про непорівнянні типи даних. Якщо ж оголосити змінну FDummy:TCursor і зробити її доступною тільки для запису, то компілятор дозволить це присвоєння, але при цьому вид курсору не зміниться: він, як і раніше, буде стрілкою.

Тривіальне вирішення цієї проблеми - оголосити клас-нащадок TCustomPanel, у конструкторі якого потрібно привласнити нове значення змінної Cursor, а від нього вже виробляти наш компонент TListAdd. Таке рішення має дві недоліки:

  1. Воно ресурсомістке - розмножуються віртуальні методи.
  2. Властивість ми ховали в інспекторі об'єктів від програміста, який використовуватиме цей компонент. Ми ж хочемо працювати з цією властивістю.

Тому вирішення даної задачі виглядає наступним чином: у конструкторі TListAdd оголошуємо оператор:

Inherited Cursor:=crHourGlass;

і все! Цього достатньо зміни курсора.

Раніше ми користувалися службовим словом inherited тільки для виклику метод предка. Дана конструкція дозволяє глибше зрозуміти значення, внесене як звернення до класу-предка. Можна звертатися і до властивостей, і методів. При зверненні до якості його можна як читати, і присвоювати йому нове значення; При цьому службове слово вherited стоїть ліворуч від знака присвоювання. Аналогічно можна викликати приховані методи предка. Звернення за ієрархією вище, ніж клас-предок, заборонено - конструкція

Inherited inherited Cursor:=crHourGlass;

не буде скомпільована.

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

Використання Hook-процедур для створення компонентів

Раніше вже згадувалося, що кожен нащадок TWinControl має процедуру, яка приймає та обробляє повідомлення. Якщо є посилання на дескриптор вікна (HWND), то можна визначити адресу цієї процедури і, що важливіше, підмінити цю адресу і таким чином обробляти отримані повідомлення своїм способом. Як правило, ніхто не пише повністю оброблювачі всіх повідомлень; Найчастіше викликається старий метод за умовчанням. При цьому нова процедура використовується як фільтр: при надходженні будь-якої події виконується код. Фактично це «шпигун» у TwinControl: нам повідомляють про надходження будь-якого повідомлення і можна виконати будь-який код. При правильній реалізації Hook-процедури TWinControl продовжує працювати як завжди, не підозрюючи, що своїми повідомленнями він ділиться з кимось.

Hook-процедура визначається так:

Procedure(var Message:TMessage) of object;

Вона залежить від змінної типу TMessage, де міститься вся інформація про повідомлення. Але визначити цю процедуру недостатньо. Вона має копіюватися для кожного TWinControl, до якого буде приєднано. Це досягається викликом WinAPI-методу MakeObjectInstance. Як параметр цей метод приймає метод об'єкта, робить його копію в пам'яті і повертає адресу нового методу. Зрозуміло, що у своїй резервуються системні ресурси, які потрібно повернути системі. Це досягається викликом методу FreeObjectInstance.

Ще одна важлива умова: перед руйнуванням TWinControl має бути відновлено зв'язок зі старою процедурою обробки повідомлень, інакше ресурси не будуть повернуті системі. Отже, доведеться запам'ятовувати покажчик на стару процедуру, яку можна дізнатися викликом методу Win API GetWindowLong із параметром GWL_WNDPROC. Цей покажчик буде також використовуватися для виклику обробників подій TWinControl за замовчуванням. Зворотний метод – SetWindowLong – використовується для встановлення Hook-процедури.

Отже, сформулюємо завдання наступної вправи. Припустимо, ми хочемо створити компонент, який змушуватиме їсти при натисканні кнопки миші інші компоненти – нащадки TWinControl. Зрозуміло, що цей компонент не слід показувати під час виконання програми, тому як його предок класу виберемо TComponent. Ім'я класу визначимо як TBeepWnd. У секції private визначимо три змінні:

FOldProc,FNewProc:pointer;

FControl: TWinControl;

З назв ясно, що ми запам'ятовуватимемо посилання на стару процедуру в змінній FOldProc, посилання на нову процедуру (після виконання методу MakeObjectInstance) буде зберігатися в змінній FNewProc. І в змінній FControl зберігатимемо посилання на елемент керування, на який зараз «повішена» Hook-процедура. Визначимо три методи у цій же секції:

Procedure HookProc(var Message:TMessage); procedure HookWindow(W:TWinControl); procedure UnhookWindow;

та у секції implementation реалізуємо їх:

У самій Hook-процедурі перехоплюється повідомлення, яке відбувається реакція – WM_LBUTTONDOWN. З іншого боку, кожна Hook-процедура повинна обробляти повідомлення WM_DESTROY. Це останнє повідомлення, яке передається вікну, перш ніж воно буде зруйноване. Наша реакція – відновити попередній метод викликом наведеного нижче методу UnhookWindow. І нарешті, скрізь викликаються обробники повідомлень за замовчуванням методом CallWindowProc. Забути обробник події за замовчуванням – те ж саме, що забути ввнесені в обробник події, в 80% випадків це призведе до некоректної поведінки програми. У жодному разі не можна забувати надавати результат виклику методу CallWindowProc полю Result змінної Message! Код у цьому випадку не працюватиме!

Procedure TBeepWnd.HookWindow(W:TWinControl); begin if csDesigning в ComponentState the begin (Checking if component at design or run-time) FControl:=W;<>Exit;<>end;

if FControl

Procedure TBeepWnd.UnhookWindow; begin if (FControl=nil) or (FOldProc=nil) or (FNewProc=nil) then Exit; (No hook was installed) SetWindowLong(FControl.Handle,GWL_WNDPROC,integer(FOldProc)); (Set old window procedure) FreeObjectInstance(FNewProc); (Free resources) FControl:=nil; (Initiate variables) FOldProc:=nil;

FNewProc:=nil; end;

Цей метод відновлює старий обробник події. Він викликається з методу HookProc і повинен викликатися з деструктора компонента - знімати Hook необхідно як при руйнуванні вікна, так і при руйнуванні даного компонента. Метод SetWindowLong з адресою старого методу відновлює старий обробник повідомлень. Після цього слід повернути ресурси системі викликом методу FreeObjectInstance.

Отже, базові методи роботи з Hook-процедурою визначені. Тепер необхідно переписати деструктор, щоб Hook-процедура знімалася при руйнуванні цього компонента:

Destructor TBeepWnd.Destroy; begin UnhookWindow;

inherited Destroy; end;

І нарешті, в секції, що публікується, визначимо властивість, яка буде відображатися в інспекторі об'єктів:

property Control:TWinControl read FControl write HookWindow;

Для встановлення нового компонента посилаємося на раніше певний метод, який під час виконання програми негайно «повісить» Hook-процедуру на компонент, який буде їсти при натисканні кнопки. Нагадаємо, що замість оператора Beep можна написати будь-який код, що виконується.

Все, про що розповідалося в попередніх розділах, стосується створення коду програми, яка буде поширюватися для користувачів. Проте середовище розробки Delphi дозволяє модифікувати себе. Для цього не потрібно знання спеціальної мови, оскільки всі методи зміни середовища розробки пишуться на Delphi. Тут ці методи, а саме редактори властивостей та редактори компонентів, розглянуті частково у плані створення інструментів для роботи з компонентами. При читанні матеріалів даного розділу слід чітко розуміти, що кінцевий користувач, який працює з вашим додатком, ніколи не побачить ні редактора властивостей, ні редактора компонентів – вони створюються для програмістів і працюють лише у середовищі Delphi.

Редактори властивостей

Під час розробки програми властивості відображаються в інспекторі об'єктів. Зверніть увагу: властивості інспектора об'єктів редагуються по-різному. Деякі властивості (Width, Caption) можуть визначити лише нове текстове значення. Властивість типу Cursor надає список, що розкривається, клацнувши по якому можна вибрати значення. Властивість типу TFont має знак "+" зліва; при натисканні по ньому воно розгортається, даючи можливість модифікувати окремі поля. Крім того, праворуч є кнопка з трьома точками (elliptic button), при натисканні на якій з'являється діалог редактора властивостей.

Кожна з перерахованих вище властивостей має свій редактор, і великою перевагою середовища розробки Delphi є можливість створити свої редактори властивостей. Нові редактори властивостей досить часто зустрічаються серед компонентів, що поширюються. Але до них треба ставитись обережно: спочатку виконати тести на комп'ютері, де за потреби можна повторно інсталювати Delphi. Як правило, вони створюються кваліфікованими програмістами і претензій до коду не буває, але часто забувають включити в редактор властивостей, що поширюється, яку-небудь DLL. Після інсталяції такого редактора ми отримуємо низку властивостей, які неможливо редагувати, – старий редактор перекритий, а новий не працює.

Перед створенням нового редактора властивостей є сенс подумати, чи варто це робити – серед стандартних редакторів, ймовірно, можна знайти відповідний. Якщо ж доведеться робити редактор властивостей, необхідно дотримуватися правила: слід уникати створення редакторів для стандартних типів даних (integer, string та ін.). Інші програмісти звикли до стандартних редакторів і ваш може їм не сподобатися. Отже, доведеться виявити скромність та реєструвати редактор для свого класу, а не для класу TComponent. Якщо ваш редактор властивостей сподобається програмістам, більшість з них зможе самостійно змінити реєстрацію так, щоб редактор працював для всіх компонентів. Питання реєстрації редактора ми обговоримо нижче.

Отже, поставимо модельне завдання, для реалізації якого необхідно буде реалізувати редактор властивостей. Припустимо, якийсь компонент має властивість – день тижня. В принципі, для введення дня тижня можна скористатися стандартним редактором зі списком, що випадає. Однак ми хочемо, щоб програміст на етапі розробки міг вводити день тижня, задаючи або його порядковий номер (1-понеділок, 2-вівторок і т.д.), або текст національною або англійською мовою. При введенні тексту допускається змішання великих і малих літер.

Насамперед необхідно створити компонент, у якому зберігатиметься день тижня. Створимо новий компонент викликом команди Component/New component. Як клас предка виберемо TComponent і дамо новому класу ім'я TDayStore. Після цього встановимо компонент палітру. Тепер треба вирішити, як зберігати день тижня. Зрозуміло, що для однозначної ідентифікації та економії ресурсів його слід зберігати як ціле число з допустимими діапазонами 1-7. Однак, якщо ми зібралися створювати редактор властивостей, слід згадати правило про створення нових редакторів для вже наявних типів. Тому визначимо новий тип - TDayWeek, причому всі операції з ним будемо робити як з цілими числами. Визначимо змінну FDay у секції private компонента. Оскільки ця змінна ініціалізуватиметься значенням 0 при відпрацюванні конструктора за замовчуванням, а це число знаходиться за межами допустимих значень, необхідно переписати конструктор. На закінчення визначимо властивість DayWeek у секції published для відображення його в інспекторі об'єктів. Остаточний варіант компонента виглядає так:

Type TDayWeek=type integer;

TDayStore = class(TComponent) private (Private declarations) FDay:TDayWeek;

protected ( Protected declarations ) public ( Public declarations ) constructor Create(AOwner:TComponent); override;

published (Published declarations) property DayWeek:TDayWeek read FDay write FDay;

end; … implementation constructor TDayStore.Create(AOwner:TComponent); begin inherited Create(Aowner);

FDay:=1; end;

  1. Слід звернути увагу до рідкісну конструкцію визначення нового типу

    TDayWeek=type integer;

    Таким чином, вводиться новий тип даних, який має той же розмір, що і тип integer, всі операції над цим типом даних здійснюються як з цілими числами. Сенс цієї операції – оголосити новий тип даних, щоб наш редактор властивостей був застосовний саме до нього і не торкався інших типів даних.

    Тепер створимо редактор властивості TDayWeek. Для цього до наявного проекту додамо нову форму, запам'ятаємо її під будь-яким відповідним ім'ям (DayPropE.pas) та виключимо з проекту. Після цього відкриємо форму як окремий файл і реалізовуватимемо в ній редактор властивостей. На першому етапі форма нам не знадобиться, але згодом ми реалізуємо на ній діалог.

  2. Модуль для створення редакторів властивостей називається DsgnIntf.pas (Design Interface), у ньому визначено базовий клас TPropertyEditor та класи-нащадки, призначені для редакції стандартних властивостей – TIntegerProperty, TFloatProperty, TStringProperty та ін. Механізм роботи редакторів властивостей полягає в наступному:
  3. Викликається метод SetValue, коли програміст ввів нове значення властивості інспектора об'єктів. Як параметр передається новий рядок. У методі вона має бути проаналізована та приведена до типу редагованої властивості.

Методи GetValue та SetValue є віртуальними, при їх переписуванні створюються нові редактори властивостей. Отже, тепер можна розпочати створення нового редактора властивостей.

Пошлемося в секції uses модуля DayPropE.pas на модуль DsgnIntf ​​і визначимо у секції Interface новий клас:

Type TDWPropED=class(TPropertyEditor) public function GetValue:string; override;

procedure SetValue(const Value:string); override;

end;

  • У секції реалізації слід реалізувати обидва ці методи. При цьому нам додатково знадобиться список назв днів тижня – у початковій постановці завдання потрібно, щоб програміст мав можливість вводити день тижня:
  • Const DayWeek:array of string = ("Понеділок", "Вівторок", "Середовище", "Четвер", "П'ятниця", "Субота", "Неділя");
  • DayWeekEn:array of string = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
  • Огляд
  1. У секції реалізації слід реалізувати обидва ці методи. При цьому нам додатково знадобиться список назв днів тижня – у початковій постановці завдання потрібно, щоб програміст мав можливість вводити день тижня:
  2. Угоди щодо найменувань

    Вибір предка

  3. Приклад створення компонента
  4. Оскільки Delphi є відкритим середовищем і дозволяє використовувати не тільки об'єкти з Бібліотеки Візуальних Компонент (VCL) у своїй програмі, а й створювати нові об'єкти. Причому нічого іншого, крім Delphi, для цього не потрібно. Створення нового об'єкта в Delphi не є дуже складним завданням, хоча для цього і знання Windows API, об'єктно-орієнтованого програмування та ієрархії класів у VCL.

    Може виникнути питання; якщо в Delphi вже є своя бібліотека, то навіщо створювати якісь об'єкти? 1 Відповідь проста: не можна створити бібліотеку на всі випадки життя та на всі смаки. Нові компоненти, по-перше, дозволяють розширити сферу застосування Delphi: наприклад, за допомогою бібліотек об'єктів третіх фірм розробляти програми для роботи в Інтернеті.

    Натисніть “Add” та вкажіть модуль, який містить процедуру реєстрації, натисніть “OK” і після успішної перекомпіляції новий об'єкт з'явиться на панелі.

  5. Заготівля для нового компонента
  6. Серед Delphi є спеціальний експерт, що створює заготівлю для нового компонента. Викликати його можна в пункті меню File | New Component ... (див рис.2)


    Може виникнути питання; якщо в Delphi вже є своя бібліотека, то навіщо створювати якісь об'єкти? 2 : Експерт для створення нового компоненту

    У діалозі потрібно вказати ім'я нового класу (наприклад, TMyButton), предка класу (TButton) та сторінку палітри, куди помістити новий компонент (Samples). Якщо натиснути OK, то експерт створить модуль - заготівлю для нового компонента:

    unit Unit1;

    interface

    uses

    SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

    Forms, Dialogs, StdCtrls;

    type

    TMyButton = class(TButton)

    private

    (Private declarations)

    protected

    (Protected declarations)

    public

    (Public declarations)

    published

    (Published declarations)

    end;

    procedure Register;

    implementation

    procedure Register;

    begin

    RegisterComponents("Samples", );

    end;

    end.

    Модуль містить декларацію нового класу та процедуру його реєстрації на Палітрі Компонент. У процедуріRegisterComponents перший параметр – ім'я сторінки (можна вказати своє ім'я – з'явиться нова сторінка); Другий параметр - безліч об'єктів для реєстрації.

    Тепер модуль потрібно зберегти під новим ім'ям (наприклад, NEW_BTN.PAS) і приступити до дописування нових властивостей та методів. Після того, як ця робота закінчена і новий компонент налагоджений, можна додати його до Палітри (див. попередній розділ). Але перед цим бажано створити файл ресурсів, в якому лежатиме піктограма для представлення даного об'єкта на панелі Компонент. Файл ресурсів можна створити за допомогою програми Resource Workshop, називатися він повинен так само, як модуль реєстрації компонента і мати розширення. DCR (тобто якщо об'єкт реєструється в модулі NEW_B TN .PAS, тоді ім'я файлу ресурсів буде NEW_BTN.DCR). У файлі ресурсів повинен бути ресурс типу BITMAP - картинка розміром 28x28 точки (можна менше), назва картинки повинна збігатися з ім'ям класу (у нашому випадку TMYBUTTON).

  7. Const DayWeek:array of string = ("Понеділок", "Вівторок", "Середовище", "Четвер", "П'ятниця", "Субота", "Неділя");

Якщо ви розглядали вихідні тексти VCL, то могли бачити, що вони дотримуються кількох простих угод щодо нових класів. Delphi цього не вимагає, імена методів, властивостей тощо. можуть бути будь-якими, компілятор це байдуже. Але якщо дотримуватися цих угод, то розробка нових компонентів та читання вихідних текстів стане значно простішою.

Отже:

  • Всі декларації типів починаються на літеру T. Ще раз Delphi не вимагає цього, але це робить очевидним, що "TEdit", наприклад, є визначення типу, а не змінна або поле класу.
  • Імена властивостям потрібно давати легко читаються та інформативні.
  • Потрібно пам'ятати, що користувач їх бачитиме в Інспекторі Об'єктів. І ім'я на кшталт "TextOrientation" набагато зручніше, ніж "TxtOr". Те саме стосується методів.
  • Методи доступні користувачеві повинні мати зручні назви.
  • При створенні властивостей типу Event ім'я такої властивості повинно починатися з On (наприклад, OnClick, OnCreate і т.д.).
  • Ім'я методу читання властивості повинен починатися зі слова “Get”.

Наприклад, метод GetStyle повинен читати для властивості Style.

  1. DayWeekEn:array of string = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");

Ім'я методу для запису властивості має починатися зі слова “Set”.

  • Наприклад, метод SetStyle повинен виконувати запис якість Style. Внутрішнє поле зберігання даних властивості має носити ім'я, що починається з літери “F”.
  • Наприклад, властивість Handle могла б зберігатися у полі FHandle. Звичайно, є винятки з правил. Іноді буває зручніше порушити їх, наприклад, клас TTable має властивості типу Event, які називаються BeforePost, AfterPost і т.п.
  • Перш, ніж приступити до написання коду, потрібно визначитися хоча б приблизно, що за компонент ви збираєтеся робити. Далі, виходячи з його гаданих властивостей, визначте клас-предок. У VCL є кілька базових класів, рекомендованих для успадкування: TObject
  • - Можна використовувати як предок, якщо з цим компонентом не потрібно працювати під час дизайну. Це може бути, наприклад, клас, що містить значення змінних середовища (environment) або клас для роботи з файлами INI. TComponent
  • - Відправна точка для багатьох невидимих ​​компонентів. Цей клас має вбудовану можливість зберігати/зчитувати себе в потоці під час дизайну. TGraphicControl
  • - Використовуйте цей клас для створення видимих ​​компонентів, яким не потрібний handle. Такі компоненти малюють прямо на поверхні і вимагають мало ресурсів Windows. - Клас на кшталт TEdit чи TButton. Використовуються з метою довизначення їх властивостей та методів або перевизначення значення властивостей, які приймаються за умовчанням.
  1. Огляд

Наприклад створимо новий клас, мутант TButton, у якому змінимо значення за умовчанням властивості ShowHint на True і додамо нову властивість - лічильник натискань на кнопку. Заготовка модуля для створення нового компонента вже є (див. Заготівля для нового компонента). Тепер вихідний текст виглядає так:

unit New_btn;

interface

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

type

TMyButton = class(TButton)

private

(Private declarations)

FClickCount: Longint;

protected

(Protected declarations)

public

(Public declarations)

конструктор Create(AOwner: TComponent); override;

procedure Click; override;

property ClickCount: Longint read FClickCount write

  • FClickCount;
  • published

    (Published declarations)

    end;

    procedure Register;

    implementation

    конструктор TMyButton.Create(AOwner: TComponent);

    begin

    inherited Create(AOwner);

    ShowHint:=True;

    FClickCount: = 0;

    end;

    procedure TMyButton.Click;

    begin

    Inc(FClickCount);

    inherited Click;

    end;

    procedure Register;

    begin

    RegisterComponents("Samples", );

    end;

    end.

    Щоб перевизначити початкове значення якості під час створення об'єкта, потрібно переписати конструкторCreate, в якому і привласнити цій властивості потрібне значення (не забувши перед цим викликати конструктор предка).

    Нова властивість для підрахунку натискань на клавішу називаєтьсяClickCount. Його внутрішнє поле збереження значення - FClickCount має тип Longint, ємності поля вистачить надовго.

    Ми вже ознайомились із компонентами Delphiу статті , і хоч ми ще нічого не розуміємо в програмуванні, але все ж таки, я думаю, що нам уже хочеться якнайшвидше почати створювати щось самостійно. Тому саме зараз я пропоную написати свій перший додаток на Delphi і розглянути, як і куди пишеться код програми, а також подивитися, що робить Delphi, створюючи програми, і як влаштований проект, що створюється. Ну, а після цього ми перейдемо до подальшого вивчення теорії.

    У комп'ютерній літературі прийнято писати першу програму, яка виводить на екран напис “HelloWord”, ми ж дещо переінакшаємо і створимо свій перший додаток, який виводитиме напис "HelloDelphi".

    Зрозуміло, для початку нам потрібно запустити сам Delphi. Після того, як перед нами відкрилося вікно оболонки – створюємо новий проект File | New | VCL Forms Application - Delphi.

    Давайте подивимося на менеджер проектів. На малюнку нижче показано вікно, в якому розкрито усі гілки дерева, щоб ми могли подивитися на всі складові нового проекту.

    Малюнок. Менеджер проекту, створюваного програми

    У менеджері проектів з'явилося ціле дерево. Давайте розглянемо кожен пункт цього дерева.

    ProjectGroup1 (Заголовок дерева)- Ім'я групи проектів. В одній групі проектів може бути кілька програм. У нашому випадку ми створили одну нову програму, тому в групі буде тільки вона. Якщо ви натиснете кнопку New (Новий) у вікні менеджера проектів та створіть нову програму, то вона буде додана до існуючої групи проектів.

    Project1.exe- Ім'я проекту (додатки). Коли ми створюємо нову програму, Delphi дає йому ім'я Project плюс порядковий номер.

    Unit1.pas- Модуль. Проект складається із модулів. Кожне вікно програми зберігається в окремому модулі, а ми бачимо на екрані, що наша програма має вікно, і саме воно знаходиться в ньому. Файли із розширенням pasмістять вихідний код модуля. Ім'я файлу таке саме, як і у модуля.

    Unit1.dfm– це візуальна форма. Вона зберігається у файлі з таким же ім'ям, як у модуля, але з розширенням dfm.

    Коли у нас у проекті кілька додатків, то лише одна з них є активною, і саме її ми можемо виконувати та налагоджувати в середовищі оболонки Delphi. Ім'я активної програми написане жирним шрифтом. Щоб змінити активну програму, достатньо двічі клацнути на його ім'я лівою кнопкою миші або клацнути правою на ім'я потрібного проекту і з контекстного меню вибрати Activate (Активувати).

    Але зараз ми працюватимемо лише з одним додатком, тому якщо ви створили два, то друге треба видалити. Для цього виділяємо ім'я програми та натискаємо на клавіатурі кнопку Delete. Перед нами з'являється вікно з підтвердженням видалення. Якщо натиснути Yes (Так), програма буде видалена з групи проектів.

    Слід зазначити, що файли з диска не видаляються. Вони залишаються на місці, але не відображаються у нашому проекті. Тому якщо ми зберегли проект і файли нам більше не потрібні, можна знайти ці файли і видалити вручну. Якщо ми не встигли зберегти файли, то, звичайно, їх на диску не буде.

    Давайте збережемо наш новий додаток. Для цього виберемо з головного меню File | SaveAll. Перед нами з'явиться стандартне вікно збереження файлу. Для початку Delphi запропонує ввести ім'я модуля. За промовчанням вказано поточне ім'я Unit1.pas. Давайте змінимо його на MainUnit і натисніть кнопку Save (Зберегти).

    Тут слід зазначити, що не можна вводити імена з пробілами чи російською мовою. Якщо ви спробуєте ввести щось подібне, то буде помилка, ваш файл не буде збережений і доведеться знову повторювати процедуру збереження. Не забудьте вибрати папку, куди ви хочете зберегти модуль та проекти. Бажано, щоб усі файли одного проекту зберігалися в одній папці принаймні на початковому етапі, поки ви не наберетеся досвіду.

    Після того, як ми зберегли MainUnit, Delphi запросить у нас ім'я майбутнього проекту. Оскільки ми вирішили писати новий додаток під назвою HelloDelphi, то тут давайте і введемо HelloDelphi. Ім'я проекту також як і ім'я модуля має вводитися без пробілів і лише латиницею. Після введення імені проекту можемо натискати кнопку Save (Зберегти). Проект збережеться у файлі під ім'ям HelloDelphi.dpr. Коли ми захочемо знову відкрити цей проект, нам потрібно відкривати саме цей файл. Не потрібно відкривати файли з розширенням pas, тому що це лише складова частина проекту. Відкривати потрібно файли з розширенням dpr.

    Намагайтеся вибирати імена, що найточніше відображають вміст модуля, щоб потім легше було розібратися, для чого призначені файли у великих проектах. До того ж бажано пам'ятати, що ім'я проекту задає ім'я майбутнього програмного файлу проекту, що виконується. Якщо ви залишите ім'я Project 1, то і ім'я файлу, що виконується Project1.exe.

    Зберігати проекти бажано в окремих папках. Для кожного проекту краще відводити окрему папку, тому що кожен проект складається з безлічі файлів, і коли ми матимемо великі проекти, то ми не зможемо відокремлювати їх один від одного, якщо вони будуть знаходитися в одній папці. Всі додаткові форми або модулі, які ми створюватимемо для проекту, бажано також зберігати в папці цього проекту. У такому разі нам буде простіше їх копіювати на інший комп'ютер, архівувати чи переносити до іншої папки.

    Давайте подивимося, як змінився наш менеджер проектів. Як бачите, ім'я проекту змінилося HelloDelphi, а ім'я модуля на MainUnit.

    Тепер давайте відкриємо папку, в яку ми зберегли наш проект, і подивимося, які там присутні файли.

    1. HelloDelphi.cfg- файли з розширенням cfg, містять конфігурацію проекту.

    2. HelloDelphi.dof- файли з розширенням dof, містять опції проекту.

    3. HelloDelphi.dpr- файли з розширенням dpr, Це сам проект. У цьому файлі знаходиться опис модулів, що використовуються в проекті, і код ініціалізації програми. Його можна використовувати для написання коду. У майбутньому ми дізнаємося, що можна писати в цьому модулі і навіщо.

    4. HelloDelphi.res- файли з розширенням res, містять ресурси проекту, наприклад, такі як іконки, курсори та ін. За замовчуванням Delphi поміщає в цей файл тільки іконку, але це не означає, що ви не можете використовувати файл для зберігання інших ресурсів.

    5. MainUnit.pas- файли з розширенням pasмістять вихідний код модулів.

    6. MainUnit.dfm- файли з розширенням dfm, Містить візуальну інформацію про форму.

    7. MainUnit.ddp- файли з розширенням ddp, Визначають допоміжні файли модуля, наприклад, діаграми. Якщо ви не використовуєте діаграми, можете видаляти ці файли, хоча вони все одно будуть генеруватися.

    8. MainUnit.dcu- файл із розширенням dcuпредставляє відкомпільований модуль проекту в проміжному форматі. Коли компілюється програма, всі модулі компілюються у файли формату DCU, а потім збираються в один і виходить один файл, що виконується. Якщо модуль не змінювався з останньої компіляції, Delphi пропустить його, а під час складання буде використовувати існуючий файл формату DCU, щоб збільшити швидкість компіляції. У вас поки що не може бути цього файлу, тому що ви ще не компілювали свій проект.

    Файли вихідних кодів (з розширенням pas) — це текстові файли, які ми редагуватимемо в редакторі коду. Файли візуальних форм (з розширенням dfm) створюються автоматично, і в них зберігатиметься інформація про те, що знаходиться на формі, а також налаштування самої форми. Я відкрив цей файл за допомогою Блокноту, і ось що я там побачив:

    object Form1: TForm1
    Left = 0
    Top = 0
    Caption = "Form1"
    ClientHeight = 213
    ClientWidth = 455
    Color = clBtnFace
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = "Tahoma"
    Font.Style =
    OldCreateOrder = False
    PixelsPerInch = 96
    TextHeight = 13
    End

    Перший рядок ідентифікує об'єкт, його ім'я та тип. Потім йде перерахування властивостей об'єкта та значення, які їм надано. Опис властивостей компонента закінчується ключовим словом end.

    Якщо у вас виникла проблема з відкриттям форми, ви можете відкрити файл візуальної форми в текстовому редакторі та підправити потрібну властивість. Це може бути потрібним, коли на формі є компонент, який з'єднується з базою даних. Якщо з'єднання активно і база недоступна, при відкритті форми Delphi намагатиметься з'єднатися з базою даних, і при невдалому з'єднанні форма може не відобразитися. У цьому випадку потрібно відкрити такий файл у текстовому редакторі та відредагувати властивості з'єднання з базою. Можна вимкнути з'єднання або підправити шлях до іншої бази даних (про самі бази даних ми говоритимемо пізніше).

    А тепер повернімося до нашої програми HelloDelphi, яку ми повинні написати. Спочатку подивимося, що ми вже маємо. В принципі, ми нічого особливого не зробили, але ми вже маємо готове вікно, яке можна перетворити на програму. Для цього потрібно скомпілювати проект. Щоб скомпілювати проект, вибираємо з меню пункт Project | Compile HelloDelphi, або натискаємо Ctrl+F9. Якщо ми нічого не змінювали в налаштуваннях Delphi, то має з'явитися вікно стану компіляції.

    Малюнок. Вікно стану компіляції в Delphi

    Давайте розберемося, що показує нам вікно.

    У цьому вікні досить добре відображається стан компіляції. Інтерес становлять три значення.

    Hints- Повідомлення. Це прості повідомлення, які вказують на місця, де можна покращити код. Наприклад, ви оголосили змінну, але не користувалися нею. У цьому випадку з'явиться відповідне повідомлення. Це, звичайно ж, не помилка, і програма все ж таки буде скомпільована. Але завдяки цим повідомленням ви зможете побачити, де було оголошено зайву змінну або, можливо, просто щось було забуто.

    Warning- Попередження. На них потрібно звертати більшу увагу. Наприклад, ви оголосили змінну, потім спробували її використовувати, не надавши початкове значення. І тут з'явиться попередження. Це знову ж таки не помилка, і програма буде скомпільована, але Delphi попереджає вас про можливу помилку. Такі попередження потрібно перевіряти, тому що ви дійсно могли забути щось зробити, і це може призвести до фатальної помилки виконання програми.

    Errors- це вже справжні помилки. Вони вказують на ті місця, де було допущено грубу помилку, через що програма не може бути скомпільована.

    Як бачимо, жодних повідомлень, попереджень чи помилок у нас немає. І це зрозуміло, адже ми ще нічого не робили та не встигли зіпсувати створену для нас заготівлю. Програму скомпільовано. Просто натискаємо кнопку ОК і це вікно закривається. Можна зробити так, щоб вікно автоматично зникало після завершення компіляції, для цього потрібно поставити галочку в Automatically close on successful compile (Автоматично закривати після успішної компіляції), але я не рекомендую цього робити.

    Тепер повернімося до папки, де ми зберегли проект і подивимося, що в нас змінилося. У цій папці з'явився виконуваний файл HelloDelphi.exe. Запустимо його, і ми побачимо пусте вікно.

    Давайте змінимо заголовок нашої форми на HelloDelphi. Як відомо, у Delphi всі об'єкти, а значить, і вікно програми теж є об'єктом. Заголовок вікна - це швидше за все властивість вікна. Для того, щоб змінити цю властивість, потрібно перейти в об'єктний інспектор (вкладка Properties (Властивості)), знайти властивість Caption (Заголовок) і ввести в його поле слово HelloDelphi (зараз у нас там написано Form1 і при запуску HelloDelphi.exe у нас з'являється форма із заголовком Form1). Після цього можна натиснути Enter або просто перейти на інший рядок з іншою властивістю.

    Після цього давайте запустимо нашу програму. Для цього можна знову скомпілювати її та запустити файл. Однак цього разу ми діятимемо інакше. Вибираємо з меню Run (Виконати) пункт Run (або натискаємо клавішу F9 на клавіатурі). Delphi відразу відкомпілює та запустить готову програму. Як бачимо, програмування не таке страшне, як здається на перший погляд.

    Малюнок. Об'єктний інспектор. Зміна якості Caption

    До уроку (стаття) додається вихідник, подивившись який, ви можете ознайомитися з повним вихідним кодом програми та подивитися як працює створена програма. Вихідний код супроводжується коментарями, завдяки чому ви зможете легко розібратися в ньому. Але я рекомендую робити все самостійно. Так ви краще і швидше засвоїте те, про що йшлося в цьому уроці

    Для того, щоб отримати можливість скачати вихідник DelphiДо цього уроку необхідно відвідати сайт рекламодавця. Після цього з'явиться посилання на вихідник Delphiдо уроку HelloDelphi. Створюємо свій перший додаток на Delphi
    Натисніть на це посилання

    дата публікації

    Не всі форми потрібно створювати під час запуску програми. Деякі краще створювати у процесі роботи програми.

    У якому разі форму краще створювати динамічно?

    Я виділив би два основні моменти.

    1. Якщо форма використовується рідко та велика ймовірність того, що її взагалі не викличуть. Прикладом може бути вікно "Про програму".
    2. Якщо кількість екземплярів нашого вікна може бути більшою за один.

    Як створити форму динамічно, як завжди представлю на прикладі.

    Приклад динамічного створення форми.

    1. Натисніть головне меню "File".
    2. Потім new.

    Програма сама накидала клас майбутньої форми. Т.к. створювати вікно ми будемо натискати кнопки, пропоную видалити наступні рядки коду.

    var Form2: TForm2; // Якщо Ви дали формі ім'я, то ця ділянка коду буде різнитися

    Оголошення ми організуємо локально, всередині кнопки обробника. Збережемо модуль, що вийшов.

    Тепер повертаємось до головної форми. Підключимо до неї щойно створений модуль: File->Use Unit...-> Вибираємо потрібний (Можна просто приписати в розділі Uses).

    Створимо дві кнопки. Створювати нове вікно ми будемо двома різними способами:

    procedure TForm1.Button1Click(Sender: TObject); var Form2: TForm2; begin Form2:= TForm2.Create(Application);

    Form2.Caption:= "Нова форма, спосіб 1";

    Form2.Show; end;

    procedure TForm1.Button2Click(Sender: TObject); var Form2: TForm2; begin Application.CreateForm(TForm2,Form2); Form2.Caption:= "Нова форма, спосіб 2"; Form2.Show; end; Ось все дуже просто, якщо ж у Вас залишилися якісь питання - пишіть у коментарі. Раз відповістиму.Розробка

    програмного забезпечення

    для ОС Windows та інших популярних може здійснюватися за допомогою різних типів інструментів. Серед тих, що характеризуються великою популярністю серед російських і зарубіжних програмістів, — програма Delphi. Якою є специфіка даного інструменту розробки? Які найбільш примітні його можливості? Загальні відомості про Delphi Delphi - середовище розробки

    прикладних програм , які призначені для запуску в Windows, MacOS, а також в мобільнихопераційні системи

    - iOS та Android. Характеризується простотою мови та процедур генерації коду.

    За необхідності забезпечує низькорівневу комунікацію з ОС та бібліотеками, складеними мовами C та C++. Програми, які створюються за допомогою Delphi, не вимагають сторонніх оболонок для запуску, таких як Java Virtual Machine. Delphi - середовище розробки, яке може успішно застосовуватися як професіоналами, так і в навчальних цілях. Для того щоб освоїти базові її можливості, необов'язково мати високу кваліфікацію і знання складних мов програмного продукту, про який йде мова. Коли тій чи іншій IT-компанії здійснюється обгрунтування вибору середовища розробки, Delphi стає вибором багатьох програмістів і рекомендується ними до використання. Це зв'язано з тим що дане середовищедозволяє створювати додатки в найоперативніші терміни, забезпечувати їх високу продуктивністьнавіть тих комп'ютерах, які мають скромні апаратні характеристики. Значний аргумент на користь вибору середовища розробки — його можна доповнювати за рахунок нових інструментів, не передбачених стандартним наборомрішень, які присутні в інтерфейсі Delphi.

    Вивчимо тепер те, які нюанси практичного користування можливостями Delphi.

    Специфіка інтерфейсу

    Перш за все можна звернути увагу на деякі особливості інтерфейсу середовища розробки ПЗ. Так, структура робочого простору програми передбачає одночасну роботуз кількома основними вікнами. Розглянемо цю властивість докладніше.

    Середовище розробки Delphi, 7 версії, зокрема, передбачає залучення наступних ключових модулів: дизайнера форм, редактора, палітри, інспектора об'єктів, а також довідника. У деяких модифікаціях Delphi ці компоненти можуть іменуватися інакше. Наприклад, редактору може відповідати вікно коду програми, дизайнеру вікно форми. Однак функціональне призначенняїх буде тим самим. Зазначені елементи інтерфейсу Delphiможуть доповнювати різноманітні допоміжні інструменти. Основними з погляду процедур розробки програм вважаються перші два. Але важливі також інші. Розглянемо особливості користування зазначеними модулями Delphi.

    Дизайнер форм, редактор та палітра

    За допомогою дизайнера форм розробник створює інтерфейс своєї програми. У свою чергу у редакторі пишеться її код. Багато програмістів, які рекомендують зробити вибір середовища розробки Delphi як самого оптимального рішення, як аргумент наводять простоту користування дизайнером форм. Деякі фахівці вважають, що цей процес і більше схожий на гру.

    Як тільки користувач починає створювати програму та запускає дизайнер форм, то спочатку в ньому немає жодних елементів, він порожній. Але його відразу можна заповнити за допомогою інструментів, розташованих на іншому модулі Delphi - палітрі. програми, які налаштовуються у дизайнері форм, повинні керуватися командами, які, своєю чергою, пишуться у редакторі.

    Але повернемося поки що до палітри. За допомогою неї можна розміщувати в області дизайнера форм необхідні об'єкти. Для того, щоб використовувати той чи інший інструмент, слід клацнути один раз на ньому - поки він в області палітри, вдруге - у вікні дизайнера форм. Після цього відповідний об'єкт переміститься в область розробки, і для нього можна прописувати код редактора.

    Інспектор об'єктів

    Інший істотний елемент, який містить Delphi - середовище розробки додатків для ОС Windows та інших поширених платформ - інспектор об'єктів. Можна відзначити, що інформація, що відображається в ньому, змінюється: на це впливає статус об'єкта, який вибрано в області дизайнера форм.

    Структура інспектора об'єктів така. Він складається із двох вікон. На кожному фіксуються алгоритми, що визначають поведінку відповідних компонентів. У першому відображаються властивості, у другому – події. Якщо програміст бажає внести коригування в алгоритми, які впливають конкретний компонент, задіяні можливості інспектора об'єктів. Так, наприклад, можна змінювати позиціонування тих чи інших елементів інтерфейсу програм, їх висоту та ширину.

    В інспекторі об'єктів є закладки, за допомогою яких можна перемикатися між сторінками, що відображають властивості або події, безпосередньо пов'язані з редактором. Так, якщо двічі клацнути на правій частині будь-якого з пунктів, що відображаються на екрані, то код, який відповідає тій чи іншій події, зафіксується в редакторі.

    Розробка програмного забезпечення в Delphi передбачає використання інспектора об'єктів для вирішення самих різних завдань. Це визначається тим, що за допомогою даного інструменту можна змінювати властивості практично будь-яких об'єктів, розташованих на формі, а також її самої. Дослідимо докладніше деякі особливості роботи з інспектором об'єктів.

    Інспектор об'єктів: використання можливостей

    Для того щоб зрозуміти, як функціонує інтегроване середовище розробки Delphi в частині взаємодії інспектора об'єктів і форм, можна спробувати внести зміни до властивостей деяких поширених елементів інтерфейсу ПЗ у Windows — наприклад, Memo, Button і Listbox (трохи пізніше ми досліджуємо їхню сутність докладніше). Спочатку їх потрібно розмістити на формі, використовуючи доступні засоби Delphi.

    Можна спробувати поекспериментувати із властивістю Ctl3D. Для цього потрібно клацнути мишкою на формі, після чого перейти в інспектор об'єктів і змінити значення властивостей, що розглядаються. Після цього форма значно змінить Одночасно властивість Ctl3D буде змінено кожному з елементів, розміщених у вікні розробки.

    Після експериментів ми можемо знову перейти на форму і активізувати значення Ctl3D. Після цього звернемося до елементів Memo та Listbox. Тепер можна змінювати їх властивості, розташування на формі, зовнішній вигляд. Наприклад, вибравши в пункті меню опцію Edit, а потім Size, програміст може змінити ширину і висоту об'єктів. Є варіант розташувати їх по центру, вибравши Edit та Align. Відповідні дії вплинуть на елементи, які відображаються в інспекторі об'єктів.

    За допомогою модуля Delphi, що розглядається, можна здійснювати зміну властивостей компонентів. Так, наприклад, якщо стоїть завдання визначити для них конкретний колір, тобто варіанти залучення відразу кількох інструментів. По-перше, можна ввести команду, яка відповідає кольору - наприклад, червоному - clRed, - в область По-друге, користувач може вибрати потрібний колірз списку. По-третє, є варіант двічі клацнути мишею на властивості Color - з'явиться вікно вибрання кольору. Аналогічно розробник може змінювати й інші атрибути об'єктів, наприклад, тип шрифту, його колір або розмір.

    Довідник

    Delphi — середовище розробки, яке доповнено досить докладним довідковою системою. Щоб звернутися до неї, слід вибрати в меню пункт Help. Після цього у вікні відобразиться один із зазначених нами вище програмних модуліврозглянутого середовища розробки - довідник. Особливість користування ним у цьому, що з натисканні F1 користувач отримає конкретну підказку, що відбиває специфіку залучення поточного інструмента. Наприклад, якщо програміст працює з інспектором об'єктів, він може вибрати одну з властивостей, після чого натиснути на F1 і отримати довідкову інформаціюпро відповідну опцію. Те ж саме можна робити при роботі з будь-яким іншим елементом інтерфейсу, який включає середовище розробки Delphi 7 та інші версії відповідного типу ПЗ.

    Інші елементи інтерфейсу

    Серед інших значущих компонентів інтерфейсу, що розглядається програмного рішення- Меню, панель швидкого доступу, а також редактор зображень. Щодо меню - воно дозволяє програмісту отримувати швидкий доступ до потрібним компонентам, присутнім у структурі середовища розробки Користуватися ним можна як за допомогою миші, так і за допомогою гарячих клавіш. Трохи нижче меню знаходиться панель швидкого доступу. Деякі з її функцій дублюють ті, що характерні для меню, але доступ до них здійснюється швидше. Delphi у чомусь схожий на програму Paintу Windows. Тобто за допомогою нього можна робити найпростіші коригування картинок, наносити на них написи та інші елементи.

    Засоби програмування

    Delphi - середовище розробки, яке включає велика кількістьінструментів, покликаних підвищити ефективність роботи програміста. Так, розглянуті нами вище ключові модулі доповнюються набором спеціальних інструментів. Серед таких: відладчик, компілятор, а також компоненти WinSight та WinSpector. Зазначимо, що у деяких версіях Delphi зазначені елементи потрібно інсталювати окремо. Вивчимо їхню специфіку.

    Відладчик Delphi

    Щодо відладчика даний інструментдоповнює редактор коду щодо проведення необхідної перевіркивідповідних програмних алгоритмівщодо коректності. За допомогою нього розробник може фактично вивчити свій вихідник. У деяких випадках при вирішенні такого завдання, як розробка компонентів, Delphi як самостійний продукт може бути доповнений зовнішнім налагоджувачем, який дає програмісту розширені можливості перевірки коду ПЗ, що створюється.

    Компілятор Delphi

    Вивчимо тепер специфіку компілятора розглянутого середовища розробки. Зазначимо, що у структурі Delphi може бути кілька відповідних елементів. Так, є варіант задіяти компілятор DCC, який корисний у тих випадках, коли стоїть завдання роботи з додатком у зовнішньому налагоджувачі.

    Winsight та WinSpector

    Зазначені модулі належать до тих, що потрібно встановлювати на Delphi додатково. Характеризуються відносною складністю освоєння. Однак багато програмістів, які здійснили вибір середовища розробки Delphi, вважають, що цими компонентами обов'язково потрібно вчитися користуватися. Так, модуль Winsight використовується для спостереження за повідомленнями Windows. Такий компонент, як WinSpector, потрібен для того, щоб фіксувати стан комп'ютера спеціальному файлі. Якщо під час розробки програмного забезпечення будуть спостерігатися будь-які збої, завжди можна відкрити цей файл і подивитися, що могло бути причиною неполадки.

    Стандартні компоненти

    Середовище розробки Delphi, загальні відомостіпро яку ми вивчаємо, включає низку стандартних компонентів, про які також корисно знати. Фахівці відносять до таких: MainMenu, PopupMenu, Label, Edit, Memo, Button, Checkbox, Radiobutton, Listbox, Combobox, Scrollbar, Groupbox, Panel, а також Scrollbox. Вивчимо їхню специфіку докладніше.

    Компонент MainMenu призначений для розміщення головного меню в інтерфейсі створюваної програми. Для цього потрібно помістити відповідний елемент на формі, після чого викликати властивість Items через інспектора об'єктів, а потім визначити потрібні пункти меню.

    Компонент PopupMenu призначений для розміщення спливаючих меню в інтерфейсі програми, що створюється, тобто відкриваються за допомогою клацання правою кнопкоюмиші.

    Компонент Label використовується для відображення тексту у вікні програми. Його можна налаштовувати, наприклад задавати потрібний шрифтв інспекторі об'єктів.

    Компонент Edit використовується для відображення на екрані фрагмента тексту, який користувач може редагувати в той час, як програма працює. Його доповнює компонент Memo, за допомогою якого можна працювати з текстами більшого обсягу. Цей елементвключає, наприклад, такі опції, як копіювання тексту.

    Компонент Button призначений для виконання тих чи інших дій за допомогою натискання кнопки, коли програма працює. Необхідно розмістити відповідний елемент формі, після чого вписати потрібний програмний код.

    Компонент Checkbox дозволяє відображати рядки з невеликим віконцем, у якому може ставитися галочка за допомогою миші. Схожий елемент – Radiobutton. Розрізняються вони, по-перше, зовнішнім виглядом- Другий компонент виконується у вигляді кружка, а по-друге, перший елемент дозволяє одночасний вибір декількох опцій, Radiobutton - тільки однієї.

    Компонент Listbox використовується для відображення на екрані списку, який може прокручувати користувач за допомогою миші. Чимось схожий на нього інший елемент - Combobox, проте він доповнюється можливістю вводити текст у спеціальному полі.

    Компонент Scrollbar – це смуга прокручування у вікнах. Як правило, з'являється автоматично, як тільки текстовий простір або форма з об'єктами стають більшими, ніж вікно.

    Компонент Groupbox використовується для того, щоб фіксувати порядок переміщення між вікнами при натисканні клавіші TAB. Може доповнюватися елементом Panel, за допомогою якого може здійснюватись переміщення декількох об'єктів на формі.

    Компонент Scrollbox дозволяє зафіксувати на формі область, яку можна прокручувати горизонтально і вертикально. Даною властивістю характеризуються основні вікна розробки Delphi за промовчанням. Але якщо є необхідність задіяти подібну опцію на конкретній ділянці форми, можна скористатися компонентом Scrollbox.

    Резюме

    Delphi - середовище розробки додатків з великими можливостями, в той же час, що характеризується простотою використання основних функцій. За допомогою інструментів, що входять до її структури, можна створювати самі різні типипрограм для Windows та інших популярних ОС.

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