Скачиваний:
24
Добавлен:
12.05.2015
Размер:
2.1 Mб
Скачать

239

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ УКРАЇНИ

"КИЇВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ"

Р.В.Сачок Комп'ютерне проектування обладнання хімічних виробництв –2. Комп’ютерне проектування обладнання хімічних виробництв у середовищі Borland Delphi»

Конспект лекцій

КИЇВ – 2014

Лекція 1. Вступ

Трохи історії

Спочатку ніяких мов програмування не було - для перших ЕОМ програми писалися на «чистій» машинній мові. Це було дуже важким та кропітким заняттям. Потім комусь спало на думку, що простіше створити програму, яка сама буде переводити вихідний код, написаний за певними правилами, в машинну мову. Так з'явився перший компілятор - Асемблер. Компілятор - програма, яка переводить вихідний програмний код в машинний мову, і створює повноцінний виконуваний програмний файл. Такі файли можуть мати розширення *.com та *.exe. Розширення *.com зрідка ще зустрічаються в старих програмах, які створювалися під операційну систему MS-DOS. Всі сучасні програми, створені для Windows, мають розширення *.exe.

Також існують інтерпретатори - програми, які не створюють виконуваний програмний файл. Інтерпретатори являють собою оболонку, в яку потрібно завантажити файл з вихідним текстом програми, потім інтерпретатори порядково переводять в машинний код мову, і виконують його. Найбільш відомим інтерпретатором є класичний Бейсік (Basic). Незручність використання інтерпретаторів і програмного забезпечення, створеного на них, не дозволяють використовувати їх широко. Для розповсюдження програм, створених на оболонці, необхідно на комп'ютер користувача встановити не тільки написану програму, але і сам інтерпретатор. А користувачеві доведеться навчитися користуватися цим інтерпретатором (завантажувати в нього програму, давати команду на виконання), а також навчитися користуватися самою програмою. Проте в деяких випадках інтерпретатори бувають досить корисні, наприклад, інтерпретатори PHP і Perl, використовувані в Web-програмування, виконуються на стороні сервера, і не доставляють користувачеві проблем

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

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

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

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

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

Сучасні персональні комп'ютери мають швидкий процесор, пам'ять і жорсткі диски великих розмірів, так що на цю незручність вже можна не звертати уваги. Звісно, бувають винятки - якщо при створенні програмного коду критичними є розмір файлу і швидкість його виконання, то краще використовувати Assembler або C. Така необхідність виникає при написанні операційних систем і драйверів. На сучасному ринку програмного забезпечення, однак, більш затребуваним прикладне програмування. Утилиты, програми загального призначення, програми для роботи з базами даних. І тут Delphi є безперечним лідером серед візуальних середовищ розробки програм.

Історія Delphi починається з 60-х років, коли професор Н.Вирт розробив мова високого рівня Pascal. Це була найкраща мова для вивчення програмування, і для створення програм для операційної системи MS-DOS. Потім, в 1983 році, А. Хейлсберг спільно з іншими програмістами, які тільки що організували компанію Borland, розробив компілятор Turbo Pascal, який став наступним кроком в еволюції Delphi. Потім з'явився Object Pascal, який вже використовував Об'єктно-Орієнтований підхід до програмування. Коли з'явилася перша версія Windows - Windows 3.10, Програмісти Borland створили Delphi 1. Це вже була об'єктно-орієнтована середовище для візуальної розробки програм, заснована на мові Object Pascal.

З появою Windows 95 з'явилася Delphi 2, потім Delphi 3, 4, 5. Мова програмування Object Pascal, яка була стрижнем Delphi, зазнала такі істотні зміни, що з появою Delphi 6 компанія Borland, яка вже перетворилася в корпорацію, офіційно оголосила про перейменування Object Pascal в Delphi. Тому праві ті, хто говорить, що Delphi - це візуальне середовище розробки програм. Але також праві й ті, хто стверджує, що Delphi - це один з кращих мов програмування.

На нашому курсі ми будемо вивчати Delphi 7, найбільш стабільну версію мови програмування для Win32 - тобто 32-розрядних версій Windows. З'явилися і нові версії Delphi, але вони орієнтовані на технологію .NET, за яку початківцям програмістам братися зарано. Тим більше, що ця технологія не застосовується широко, і ринок програмного забезпечення, створеного за допомогою Delphi, все одно складають програмні продукти, написані на Delphi 7, і навіть більш ранніх версій.

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

Перша програма

Традиційно при вивченні програмування прийнято створювати першу програму, яка виводить текст «Hello, world!». Не будемо відступати від традиції і створимо програму, яка виводить цей текст трьома різними способами. Але спочатку познайомимося з самої середовище програмування Delphi. Передбачається, що на цей момент Delphi 7 вже встановлена на вашому ПК. Якщо це не так, то перед подальшим прочитанням лекції встановіть Delphi 7. При завантаженні Delphi 7 ви бачите таку картину:

Рис. 1.1 Робоче середовище Delphi 7.

Познайомтеся - це Delphi. У неї є багато вікон, панелей, компонентів. З більшістю з них ми познайомимося згодом, а поки нам потрібно звернути увагу на 5 вікон:

  1. Головне вікно Delphi. Тут знаходиться основне меню, різні панелі інструментів і палітра компонентів, що складається з безлічі вкладок. 2. Конструктор форми. Тут ми візуально бачимо, як буде виглядати форма програми, тут ми будемо створювати інтерфейс, переносячи на форму різні компоненти, і розставляючи їх таким чином, щоб інтерфейс виглядав привабливим. Нам часто доводиться перемикатися між конструктором форм і редактором коду, робиться це клавішу F12. 3. Редактор коду. Тут ми бачимо вихідний код програми, який створений самою Delphi. Тут же ми будемо вводити наш власний код. 4. Об'єктний інспектор. Він призначений для управління об'єктами проекту і складається з двох вкладок - Properties (Властивості) і Events (Події). 5. Дерево об'єктів. Тут ми бачимо, який саме об'єкт в даний момент є поточним. Це вікно буде особливо корисно, коли на формі з'явиться безліч компонентів.

Коли відкривається Delphi, вона автоматично створює і підтримує новий проект (програму). На малюнку ви бачите проект, який містить тільки одну стандартну форму. Форма - це теж об'єкт, який являє собою вікно програми. Щоб програма робила щось корисне, нам доведеться вносити зміни до неї. Виведемо текст «Hello, world!» першим способом. Для цього в інспекторі об'єктів знайдіть властивість Caption. В даний момент поточних є об'єкт - форма, і властивість Caption форми відповідає за напис на системній рядку програми (синя смуга зверху будь-якого програмного вікна). За замовчуванням, властивість Caption містить напис «Form1», також називається і сама форма. Змініть цей напис на «Hello, world!» (звичайно, без лапок). Вже в процесі введення тексту ви бачите, що напис в системної рядку приймає новий вигляд. Ми ввели цей текст одним способом.

Тепер нам потрібно зберегти проект. Проект - сукупність файлів різних форматів, з яких створюється програма. Про це ми детальніше поговоримо в одній з наступних лекцій, а поки запам'ятайте правило - кожну програму (проект), яку ви створюєте, потрібно зберігати в окремій папці. Якщо ви всі проекти станете зберігати в одну папку, то дуже скоро заплутаєтеся. Щоб зберегти проект, виконаємо наступні дії: 1. Вибираємо пункт меню «File - Save All» (зберегти все), або натискаємо гарячі клавіші <Shift+Ctrl+S>, або натисніть однойменну кнопку на панелі інструментів

Рис. 1.2 Кнопки Save (Зберегти) і Save All (Зберегти все) на панелі інструментів.

2. Потім виходить вікно з пропозицією зберегти модуль - текстовий файл з вихідним кодом, що належить формі. Файл має розширення *.pas. Маємо на увазі, що кожен проект зберігається в окрему папку, тому спочатку клацнемо правою кнопкою миші по вільного місця вікна з папками, і виберемо команду «Створити Папку». Дамо папці яке-або ім'я, наприклад, «01». Після створення папки відкриваємо її.

3. Далі в полі «Ім'я файлу» вкажемо вибраний модуль. Ім'я може бути будь-яким, але обов'язково латинськими символами. Ще ім'я модуля не повинно співпадати з назвою форми. Звичайно, імена форм і модулів прагнуть робити інформативними, тобто, по імені можна буде здогадатися, що це за файл. Оскільки це головна форма проекту, дамо їй ім'я «Main», і натиснемо кнопку «Зберегти». 4. Потім нам буде запропоновано дати ім'я проекту в цілому. Ім'я проекту буде співпадати з назвою виконуваного програмного файлу. Якщо ми хочемо, наприклад, отримати файл «hello.exe», то дамо проекту ім'я «hello». Натиснемо кнопку «Зберегти».

Далі нам необхідно скомпілювати програму, тобто перевести вихідний код у виконуваний exe-файл. Для цього ми можемо вибрати команду меню «Run - Run», або натисніть гарячу клавішу F9 або натиснути кнопку «Run» на панелі інструментів (на кнопці зображення зеленої стрілки, що вказує праворуч). В результаті, програма була не тільки скомпільовано, але і запущена. Якщо ви подивіться на системну рядок Delphi, то побачите напис «Delphi 7 - hello [Running]», а вікна інспектора об'єктів і дерева об'єктів зникли. Це говорить про те, що програма знаходиться у режимі виконання. Що виконується програма має точно такий же вигляд, як наша головна форма, тільки на формі відсутній точкова сітка, призначена для полегшення дизайну. Вікно отриманої програми містить всі стандартні кнопки Windows - програми. Клацнувши по червоному хрестику в правій верхній частині вікна, закрийте програму (але не Delphi), і ви побачите колишню форму.

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

Спробуємо другий спосіб. Зверніть увагу на Палітру компонентів. Поточної є вкладка Standard, і на ній знаходиться безліч значків - компонентів. Коли ви підбивайте вказівник миші до якого-або компоненту, через деякий час вискакує підказка з ім'ям компонента. Нам потрібен компонент Label, який представлений на вкладці у вигляді кнопки із зображенням жирної букви «А». Клацніть на цій кнопці, потім клацніть по вільного місця на формі, щоб вставити компонент. Краще, якщо ви розмістите його ближче до лівого верхнього краю форми. Компонент Label з'явився на формі. Цей компонент являє собою звичайну напис. Зараз він виділено, і містить напис за замовчуванням, - «Label1». Тепер об'єктний інспектор показує властивості цьогокомпонента, а не форми. Label також має властивість Caption, яке ви можете змінити в Інспекторі об'єктів. Знайдіть це властивість, і замість «Label1» впишіть «Hello, world!». Текст у вікні Label змінився. Якщо вам не подобається місце, в якому опинився компонент, ви можете перетягнути його мишею на інше місце. Крім того, точне розташування компонента ви можете задати, якщо виділіть його, і будете натискати клавіші курсора, утримуючи натиснутою клавішу <Ctrl>. Тепер спробуйте ще одна властивість компонента Label - властивість Font (шрифт). Знайдіть це властивість в інспекторі об'єктів, і виберіть його. Праворуч з'явиться кнопочка з трьома точками, натисніть її. Відкриється стандартне вікно вибору шрифту. Тут ви можете вибрати назву шрифту, його розміри, зображення (наприклад, жирний курсив) і колір тексту. Поекспериментуйте з розміром компонента, його становищем і шрифтом. Майже всі компоненти, з якими нам доведеться мати справу, мають ці властивості, так що надалі вам буде легше освоювати новий компонент.

Знову збережете і натисніть кнопку Run (або <F9>). Переконайтеся, що напис з'явився на формі, після чого закрийте програму (але не Delphi) і поверніться до форми.

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

Для початку потрібно встановити на форму кнопку. Цей компонент також знаходиться на вкладці Standard панелі компонентів, і виглядає як кнопка з написом «ОК». При наведенні вказівника миші вискакує підказка «Button». Клацнувши по компоненту, клацніть потім з того місця на формі, де ви хотіли б бачити цю кнопку. Змінимо напис на кнопці. Переконайтеся, що кнопка виділена, і знайдіть в інспекторі об'єктів її властивість Caption. Замініть напис «Button1» на «Натисни мене!». Якщо напис уміщається на кнопку, ви можете розтягнути кнопку миші, або використовувати для цього клавіші керування курсором з натиснутою кнопкою <Shift>.Далі нам потрібно створити обробник натискання на кнопку. Обробник являє собою процедуру, в якій ми будемо писати наш код. Цей код буде виконуватися програмою всякий раз, коли користувач натисне на цю кнопку. Щоб створити цей зворотній виклик, слід двічі натиснути на кнопку на формі. Ви відразу потрапляєте в редактор коду і бачите, що процедура вже створена, курсор блимає в тому місці, де ми повинні ввести свій код. Поки що не будемо розбиратися, що тут до чого, а просто впишемо рядок:

Повний текст процедури вийде такий:

Якщо у вас так і вийшло, збережете, відкомпілюйте його і запустити на виконання. При натисканні на кнопку буде з'являтися зазначена напис. Ми створили повноцінну програму, що виводить напис «Hello, world!» трьома різними способами, зазначивши при цьому лише один рядок вихідного коду! Отриманий файл hello.exe знаходиться в зазначеній вами папки

C:\ProgrammFiles\Borland\Delphi7\Projects\01

При збереженні проекту ви можете вказувати й інші папки, і проект буде збережений за вказаною адресою. Отриманий програмний файл hello.exe тепер ви можете поширювати, наприклад, переслати одному, щоб він помилувався вашими досягненнями.

Лекція 2.

Змінні

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

Змінна - це комірка оперативної пам'яті, яка може зберігати дані якого одного типу. Змінна схожа на комірку в MS Excel, там теж у комірці можна вказати потрібний формат даних. Якщо змінна має тип даних «рядок», то в неї не можна записати число. А в змінну з типом «ціле число» неможливо записати дійсне число. В мовах програмування речовим називають число, у якого є кома, після якої є цифри, хоча б нулі:

125,00 348,24

Кожна змінна має унікальне ім'я. Для комп'ютера ім'я змінної - це адреса комірки пам'яті, де зберігаються дані. Привласненням імен (ідентифікаторів) змінним займається програміст. Імена змінних в Delphi даються за певними правилами:

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

2. Першим символом обов'язково повинна бути буква.

3. В Delphi немає різниці, які букви ви даєте змінним - великі або малі. Тобто, myperem, MyPerem, MYPEREM - це одна і та ж мінлива.

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

Типи змінних

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

1. Оголошення змінної (вказуємо ім'я і тип змінної). Мінлива оголошується в спеціальному розділі var (пізніше ми познайомимося з цим розділом).

2. Присвоєння змінної якого-значення.

Оголошення змінної виглядає так:

var Peremennaya1 : Real;

Peremennaya2, Peremennaya3 : Integer;

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

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

:=

Приклади присвоєння значень змінних:

A := 10;

B := 20.35;

C := 'Це рядок';

D := True;

A := 3+5-1;

Механізм привласнення значення працює наступним чином: спочатку розраховується значен правій частині команди, тобто, після знаку«:=». Потім результат цього значення записываетс змінну. В останньому рядку прикладу ми використовували вираз «3+5-1». Спочатку отримує результат, у нашому випадку він дорівнює 7. Потім цей результат записується в змінну. Надалі, ім'я змінної можна використовувати в різних виразах, наприклад:

A1 := 3;

A2 := A1 + 7;

A1 := A1 + 1;

У першому рядку ми записали в змінну число 3. Другий рядок містить вислів результатом якого буде число 10. А ось третій рядок цікавіше. Як ви вважаєте, що бо записано в змінну A1? Якщо ваша відповідь 4, ви абсолютно праві: спочатку розраховується результ правій частині команди, де у змінній A1 ще старе значення, потім він записується в цю змінну, змінюючи її значення.

У таблиці 2.1 перераховані основні типи змінних:

Назватипу

Опис

Пояснення

Integer

Ціле число

Змінна може вміщувати тільки цілі числаенная может, як зі знаком так і без.

Real

Речівнечисло

Змінна може приймати в якості значення цілих та дробових чисел, як зі знаком так і без.

String

Рядок

Змінна може зберігати любі символи та набори символів. В змінну String можно записати до 2 Гб символів.

Boolean

Логічний тип

Булева змінна, може бутиабо False (Брехня), або True (Істина).

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

Рядок

З цим типом змінних доводиться працювати досить часто. У прикладі вище ми вказували рядок ‘рядок’, а на минулій лекції мали справу з рядком ‘Hello, world!’. Ви вже помітили, що всі рядки повинні бути укладені в одинарні лапки. Розмір рядка практично не обмежений. Ви можете записати в рядок будь-який текстовий файл, все залежить від того, скільки місця є у Вас на диску, і яка ОЗУ у Вас встановлена.

Вивчати новий тип зручніше відразу на практиці, тому запускайте Delphi. Автоматично повинен створити новий проект. Напишемо простеньку програму, в якій попрацюємо з рядком. Всі компоненти, які нам для цього знадобляться, знаходяться на вкладці Standard Панелі компонентів.

Помістіть на форму, один за іншим, наступні компоненти: Label, Edit і Button. З Label і Button ви вже знайомі з минулого програмі - Label це проста напис, а Button кнопка на формі. Компонент Edit являє собою поле для введення користувачем якого те значення, який рядки.

Розтягніть компонент Edit, зробивши його приблизно удвічі довший. Виділіть компонент Label (одним натисканням миші!), і в його властивості Caption замість «Label1» впишіть «Як твоє ім’я?».

Тепер виділіть компонент Edit, і видаліть «Edit1» з властивості Text, залишивши там порожнє поле. Властивість Text цього компонента містить той текст, який в даний момент знаходиться в полі вводу. Взагалі, з властивостями компонента можна поводитися, як із змінними. В більшість властивостей можна заносити значення не тільки в Інспекторі об'єктів, у момент розробки форми, але і під час виконання програми.

Виділіть кнопку, і в її властивості Caption напишіть «Натисни мене!». Для краси, перемістіть її в центр форми.

Змініть розмір форми, щоб на ній не було багато вільного місця. А також у властивості Caption форми напишіть «Привітання». Нагадаємо, щоб виділити форму, потрібно один раз клацнути мишею з будь-якого вільного місця форми. Якщо ви все зробили правильно, у вас повинна вийшов така форма:

Рис. 2.1 Зовнішній вигляд форми

Тепер створимо обробник подій для кнопки. Для цього двічі клацніть по кнопці, яку ви розмістили на формі. Відразу ж ви потрапляєте в Редактор коду, і курсор блимає між рядками begin і end. Begin - це початок процедури, після нього крапка з комою не ставиться. End кінець процедури, після цього оператора крапка з комою обов'язкова. Якщо ви придивитеся, то в останньому рядку редактора коду побачите end з точкою - це кінець програми. Змінні вказуються (описуються) перед початком процедури. Отже, рядок begin потрібно буде опустити, а перед нею вписати розділ змінних var, і вказати змінну s. Процедура повинна виглядати так:

procedure TForm1.Button1Click (Sender: TObject);

var

s: String;

begin

s: = 'Привіт,' + Edit1.Text + '!';

ShowMessage (s); end;

Зверніть увагу, що коли ви поставите крапку після назви компонента Edit1, вийде список доступних властивостей, методів і подій. Коли ми впишемо першу літеру «T», список сортується - в ньому залишаться тільки команди на літеру «T», причому Delphi оцінює контекст, і залишає у списку тільки ті команди, які в цьому контексті можуть бути використані. У нашому випадку, це рядок. Властивість Text, який залишиться в списку, може бути використано в якості рядки:

Рис. 2.2 Вибір властивості зі списку - підказки.

Тепер немає потреби вводити «Text» самим - це властивість виділено в списку, і нам достатньо натиснути <Enter>, щоб вставити його в код. На майбутнє запам'ятайте: завжди року ви ставите крапку після назви компонента, дочекайтеся такого списку. Справа не тільки в тому, що так легше вводити код. Якщо список так і не з'явився, значить, ви допустили помилку. Можливо, у назві компонента, або навіть у попередній рядку. Тепер збережіть проект в окрему папку, модуль, як зазвичай, назвіть Main, а проект можете назвати, наприклад, Privet. Після збереження зберіть його і подивіться, яке повідомлення буде виходити при різних рядках, які введе користувач у полі вводу Edit1.

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

'Привет, ' + Edit1.Text + '!'

прямовкомандеShowMessage:

procedure TForm1.Button1Click(Sender: TObject); begin

ShowMessage('Привет, ' + Edit1.Text + '!'); end;

Стиль

Якщо ви надумаєте піти влаштовуватися на роботу програмістом, насамперед вас попросять показати ваші вихідні коди. І справа тут зовсім не в тому, що хтось хоче вкрасти вашу програму, щоб потім видати її за свою. Розуміючі люди в першу чергу дивляться на стиль оформлення коду. Давайтерозглянемопопереднійприклад:

procedure

TForm1.Button1Click(Sender: TObject);

var

s: String;

begin s:= 'Привет, ' + Edit1.Text + '!';

ShowMessage(s); end;

Такий код цілком працездатний, проте виглядає він не дуже «читабельно», у ньому легко заплутатися. Подивітьсятакийприклад:

procedure TForm1.Button1Click(Sender: TObject);

var

s: String;

begin

s:= 'Привет, ' + Edit1.Text + '!';

ShowMessage(s);

end;

Вже краще, не чи правда? Кожна команда розташовується на своїй власній рядку, читаність коду стала набагато легше. Однак у такому коді відразу складно розібратися, де закінчується один розділ і починається інший. Класичний стиль вимагає, щоб вкладені команди виділялися кількома пробілами, зрушувалися вправо:

procedure TForm1.Button1Click(Sender:TObject);

var

s: String;

begin

s:= 'Привет, ' + Edit1.Text + '!'; ShowMessage(s); end;

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

Коментарі

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

Коментарі бувають багаторядкові і однорядкові. Багаторядковий коментар полягає у фігурні дужки, і в цих рядках не повинно бути діючих операторів. Приклад:

{Це багаторядковий коментар!}

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

Однорядковий коментар ставиться після символів «//», тобто двох слешів. Цей коментар може знаходитися як на окремому рядку, так і після (але не до!) оператора. Приклади:

//коментар на окремому рядку

a := 'Діючий оператор'; //коментар після оператора

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

Власний Блокнот

Кожен користувач, що працює з Windows, хоч раз та використав простий текстовий редактор Блокнот. Зараз ми створимо трохи спрощену версію Блокнота, яка дозволяє вводити текст, зберігати його на диск, і завантажувати з диска. Для цього нам потрібно створити новий проект. Якщо зараз у вас вже відкрито якийсь проект, виберіть команду меню «File - Close All (Файл – Закрити всі)», потім «File - New - Application (Файл - Нове - Додаток)».

У нас є нова форма, і поки більше нічого немає. Відразу змінимо деякі властивості форми. У властивості Caption впишіть «Мій блокнот» (природно, без лапок). Властивість Name змінимо на «fMain».

Порада: щоб легше орієнтуватися в назвах модулів (фото з кодом) і форм, краще відразу виробити правила:

1. Перед назвою форми будемо вказувати маленьку букву f, щоб показати, що це саме форма.

2. Імена форм будемо підбирати інформативні, щоб було зрозуміло, з якою формою ми маємо справу.

3. Модулі форм будемо називати також, але без букви f.

4. Головну форму завжди будемо називати fMain, а модуль, відповідно, Main.

Ці рекомендації не є обов'язковими, але надалі, коли підуть проекти з безліччю форм, вони допоможуть вам орієнтуватися в назвах. Можете виробити власні правила.

Збережемо проект в окрему папку. Модуль називаємо Main, а проектом даємо ім'я MyNotebook.

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

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

Рис.2.3. Заготівля редактора текстів

Тепер виділимо першу кнопку, і властивості Caption цієї кнопки напишемо «Зберегти». На другий кнопці напишемо «Завантажити», на третьому - «Очистити».

Виділимо компонент Memo, який являє собою велике біле поле. У компонента є одна цікава властивість Lines, яке містить рядки тексту, набраного в компоненті. Докладніше з цією властивістю ми познайомимося пізніше, а поки виділимо його в Інспекторі об'єктів, натискаємо на кнопку з трьома точками праворуч від властивості і тим самим відкриємо редактор тексту. Тут можна набрати текст, який буде виведений в компонент «за замовчуванням», при кожному запуску програми. Нам просто потрібно, щоб тексту ніякого не було, тому видаліть всі рядки, які там є і натисніть «ОК». Компонент Memo очистився.

Це ще не все. Нам потрібно, щоб при введенні текст автоматично переносився на інший рядок, а користувач мав можливість його перегортати. Знайдіть властивість ScrollBars (компонент Memo повинен бути вибраним), це властивість відповідає за наявність смуг прокрутки. Виберіть значення ssVertical, щоб з'явилася вертикальна смуга прокрутки.

З інтерфейсом покінчено, залишилося ввести код, який буде виконуватися програмою. Двічі натиснемо на першу кнопку, створимо обробник подій для кнопки «Зберегти». У місці, де блимає курсор, впишемо тільки один рядок:

Memo1.Lines.SaveToFile('MyFile.txt');

Метод SaveToFile() властивості Lines компонента Memo зберігає весь текст у вказаний файл. Якщо ви не вказуєте шлях до файлу за замовчуванням файл буде створено там, звідки була запущена програма. Для другої кнопки напишемо два рядки:

ifFileExists('MyFile.txt') then

Memo1.Lines.LoadFromFile('MyFile.txt');

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

Для третьої кнопки код ще простіше:

Memo1.Clear;

Ця команда очищає компонент Memo від тексту. Ось, власне, і вся програма. Збережіть її і зберіть, перевірте, як вона працює. Оцініть легкість програмування - для створення повноцінного редактора текстів ми написали всього 4 рядки коду!

Поекспериментуйте з властивістю Font (Шрифт) компонента Memo, подивіться, яким чином буде змінюватися шрифт тексту.

Лекція 3. Цілі і речові типи. Процедури та функції.

Цілі числа

Програмістам суцільно і поруч доводиться використовувати дані цілого типу. Ціле число - це число, яке не має коми. Число може бути беззнаковим (позитивним), і зі знаком мінус (негативним). Приклади:

1

-12

1234567

У минулій лекції ми згадали лише тип Integer, як основний тип цілих чисел. Дійсно, цей тип доводиться використовувати найчастіше, однак існують і інші типи цілих чисел. В таблиці 3.1 представлені цілі типи: Таблиця 3.1. Цілі типи даних

Тип

Діапазон возможных значений

Розмір памятіпод переменную

Примітка

Integer

-2147483648 .. 2147483647

4 байта

Знакове

Cardinal

0 .. 4294967295

4 байта

Без знаку

Shortint

-128 .. 127

1 байт

Знакове

Smallint

-32768 .. 32767

2 байта

Знакове

Longint

-2147483648 .. 2147483647

4 байта

Знакове

Int64

-263263- 1

8 байт

Знакове

Byte

0 .. 255

1 байт

Без знаку

Word

0 .. 65535

2 байта

Без знаку

Longword

0 .. 4294967295

4 байта

Без знаку

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

Найчастіше вам доведеться працювати з змінними типу Integer, це найпоширеніший тип цілих чисел, він підходить майже для всіх розрахунків. Однак бувають моменти, коли не потрібно такого великого діапазону значень. Наприклад, ви будете використовувати змінну для лічильника якого-то циклу, і знаєте, що він буде тривати, приміром, від 1 до 100. У такому випадку, вказавши як лічильника тип Integer, ми даремно украдем у оперативної пам'яті 3 байти! 3 байти - це небагато, але ж у великій програмі змінних буде дуже багато, і якщо всі вони будуть витрачати пам'ять даремно, то така програма буде, м ’ яко кажучи, непрофесійною. Привчайтеся відразу витрачати стільки байт оперативної пам'яті, скільки потрібно. Не дарма ж придумали стільки типів! Якщо ви знаєте, що в змінної числа від нуля і вище, то немає ніякої необхідності брати знаковий тип, адже негативним Ваше число все одно не буде!

Дійсні числа

Як ми вже говорили раніше, дійсні числа - це числа з комою, після якої йдуть десяткові значення. Ще говорять, що вони мають плаваючу точку (запам'ятайте це визначення, воно буде часто зустрічатися). Деякі початківці програмісти вважають, що краще такий тип змінних використовувати завжди, навіть при обробці цілих чисел. Це велика помилка! Операції над числами з плаваючою точкою віднімають у процесора набагато більше часу, і вимагають більше пам'яті. Комп'ютер сприймає дійсне число, як два цілих, і робить подвійну роботупри обробці чисел до коми, і після неї. Однак іноді буває необхідно використовувати саме такий тип даних. Наприклад, якщо потрібно поділити одне ціле на інше. Добре, якщо це буде «4/2», результат теж буде цілим - 2. А якщо «4/3»? Тоді результатом буде 1,3333... і вже тут без дійсного числа не обійтися! Адже ми заздалегідь не знаємо, які числа буде ділити користувач, тому краще відразу мати на увазі, що результат може бути не цілим числом.

Як і цілі, дійсні числа мають кілька типів. У таблиці 3.2 вони представлені:

Таблиця 3.2. Речові типи даних

Тип

Діапазон возможных значень

Значущих цифр максимально

Розмір в байтах

Real48

2.9 *10-39.. 1.7 * 1038

11-12

6

Real

5.0 * 10-324.. 1.7 * 10308

15-16

8

Single

1.5 * 10-45.. 3.4 * 1038

7-8

4

Double

5.0 * 10-324.. 1.7 * 10308

15-16

8

Extended

3.6 * 10-4951.. 1.1 * 104932

19-20

10

Comp

-263+1 .. 263-1

19-20

8

Currency

-922337203685477.5808 .. 922337203685477.5807

19-20

8

Третій стовпчик таблиці вказує кількість максимально значущих цифр. Цифри, які виходять за цю межу, будуть ігноруватися. Тут важливо пам'ятати, що дійсні числа не рівні цілим. Тобто, число 3,0 не буде дорівнює 3! Щоб порівняти обидва ці числа, доведеться округлити дійсне число.

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

Відкрийте Delphi, створіть новий проект. На форму потрібно помістити три компоненти Label, три компоненти Edit і одну кнопку, щоб вийшла така картина:

Рис. 3.1. Зовнішній вигляд форми.

Порада: щоб виконати однакову операцію над декількома компонентами відразу, їх можна виділити один за іншим, утримуючи клавішу <Shift>. Наприклад, якщо таким чином виділити всі три компоненти Edit, то потім можна разом очистити їх властивість Text.

Збережіть проект під назвою MyCalc. Потім двічі клацніть по кнопці, щоб створити обробник натискання на кнопку.

Перед begin процедури слід створити розділ var, і оголосити там три змінних:

var

Perem1, Perem2 : Integer; Perem3 : Double;

Потім повернемося в тіло процедури (між командами begin і end), і присвоїмо цілим змінним введені користувачем значення. Тут потрібно зрозуміти одну важливу річ. Користувач буде вводити значення компоненти Edit, і там вони будуть зберігатися у властивості Text у вигляді строкового типу даних. Рядок не можна буде присвоїти змінної будь-якого іншого типу даних, присвоєння

Perem1 := Edit1.Text; //помилкове присвоєння - несумісність типів данихбуде помилковим. Різниця досить істотна: навіть якщо користувач вводить, здавалося б, ціле число, наприклад, 123то комп'ютер бачить рядок символів, а зовсім не число: ‘123’

Вихід - перетворити один тип даних в інший, в нашому випадку, рядок в цілий тип. Перетворенням типів доводиться займатися суцільно і поруч, у міру вивчення матеріалу ми будемо знайомитися з різними способами перетворення. Перетворити рядок в цілий тип можна за допомогою функції StrToInt(‘String’).

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

var s: String; i: Integer;

begin

s := '1234';

i := StrToInt(s); //параметр - символьна мінлива i := StrToInt('123456'); //параметр – рядок

i := StrToInt(Edit1.Text); //параметр - властивість Text компонента Edit, що має

//строковийтип

end;

Як видно з прикладу, є маса можливостей передати функцію рядок. У першому випадку перетворення ми передаємо строкову змінну s, в якій зберігається рядок ‘1234’. Функція перетворює цей рядок в ціле число, і в результаті в змінну i потрапить вже число 1234.

У другому випадку ми передаємо безпосередньо рядок ‘123456’, а в змінну i потрапляє перетворене з цього рядка число. У третьому випадку ми в якості параметра передаємо той текст, який користувач ввів у полі вводу Edit1. Тут слід зробити застереження. Функція спрацює правильно, якщо користувач ввів туди дійсно ціле число. Інакше виникне помилка. Користувач - особистість непередбачувана, тому программист в таких випадках перед перетворенням типів завжди робить перевірку - а чи дійсно в полі є тільки цифри від 0 до 9? Чи немає там випадково букви або комою? Таку перевірку ми навчимося робити пізніше. Поки що доведеться самим стежити, щоб в цих полях введення були тільки цілі числа.

Повернемося до програми. Відразу після begin присвоюємо цілим змінним значення, які ввів користувач:

Perem1 :=StrToInt(Edit1.Text; Perem2 := StrToInt(Edit2.Text);

У третю, речову змінну, ми повинні записати результат ділення першого числа на друге. Тут може критися ще один «підводний камінь» - що, якщо у друге поле користувач ввівчисло 0? Ще зі школи всі ми знаємо, що на нуль ділити не можна. Якщо ж ми спробуємо це зробити, то комп'ютер, в кращому разі, зависне. Тут знову доведеться робити перевірку на правильність введених даних, ставити, як кажуть, «захист від дурнів». Докладніше про такі перевірки ми поговоримо на наступних лекціях, коли вивчимо умовні конструкції. А поки що просто наберіть цей код після попередніх двох рядків присвоєння:

{захист від дурнів:}

IfPerem2 = 0 thenbegin //якщо це нуль, то:

ShowMessage('нуль ділити не можна!'); //виводить повідомлення

Edit3.Text := '0'; //як результат записуємо нуль

end elsebegin //інакше:

Perem3 := Perem1 / Perem2; //ділимо

Edit3.Text := FloatToStr(Perem3); //перетворимо речовий в рядок і записуємо

//результат end;

Тут слід звернути увагу на передостанній рядок. Функція FloatToStr() в якості параметра приймає дійсне число, і повертає це ж число у вигляді рядка. Наприклад, в результаті перетворення

s := FloatToStr(123.45);

змінної s буде присвоєно рядок ‘123.45’, яку потім вже можна буде вивести користувачеві в якості результату.

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

Edit3.Text := FloatToStr(Perem1 / Perem2);

те потреба у використанні дійсної змінної Perem3 відпадає. Спробуйте, як працюють обидва варіанти.

Процедури

Це дуже важлива тема, зверніть на неї особливу увагу!

Раніше мови програмування були построчными. Єдиним варіантом повернення до потрібної рядку був оператор GOTO. Дуже багато помилок було зроблено цим оператором! Сучасні мови програмування також мають цей оператор, але застосовувати його вважається поганим тоном.

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

procedureNameProc(Param : Тип); var

//оголошення змінних(необов'язково)

begin //тіло процедури

end;

Викликати таку процедуру можна, просто вказавши її ім'я. Перевіримо це на практиці. Повернемося до нашого проекту, і вище процедури обробки кнопки створимо таку процедуру:

procedure Soobshenie; begin

ShowMessage('Помилка! На нуль ділити не можна!'); end;

У цій процедурі ми не використовуємо змінних, тому розділ var відсутній. Все, що робить наша процедура - виводить повідомлення про те, що на нуль ділити не можна. Зверніть увагу, що якщо немає вхідних параметрів, то дужки вказувати необов ’ язково. Тепер знову перейдемо до процедури обробки натискання кнопки, і замість виводу повідомлення, що на нуль ділити не можна, проведемо виклик процедури:

Soobshenie;

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

procedure Primer(a,b: Integer);

begin

a*b;

end;

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

Primer(10, 20); //передаємо цілі числа

Primer(a, 100); //передаємо змінну a з цілим числом, і ціле число

Primer(c, d); //передаємо дві змінних з цілим числом

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

Функції

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

function NameFunc(Param : Тип) : Тип_возвращаемого_значения; var //оголошення змінних (необов'язково)

begin //тіло процедури

Result := результат обчислень; end;

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

Є ще один спосіб повернути функції результат обчислень: використовувати змінну з таким же ім'ям, як і ім'я функції. Цю змінну теж оголошувати не потрібно. У нашому прикладі, рядок

Result := результат обчислень;

буде повністю ідентичною рядку

NameFunc := результат обчислень;

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

function Delenie(a,b : Integer) : Real;

begin

Result :=a/b;

end;

Тепер замінимо той рядок, де в третю змінну записується результат ділення перших двох, на виклик функції і передачу їй цих двох чисел:

Perem3 := Delenie(Perem1, Perem2);

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

Події

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

Події можуть бути різними - зміна тексту в полі Edit, натискання кнопки миші або клавіші, або просто миша опинилася над компонентом.

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

Виділимо компонент Edit1.Перейдемо в інспекторі об'єктів на вкладку Events (події).

Двічі клацнемо за події OnChange (Зміна).

Створиться процедура обробки події, і ми потрапимо в редактор коду. Там ми впишемо два рядки:

Edit2.Clear;

Edit3.Clear;

Тепер вставимо ще одну «захист від дурнів». Адже третє поле потрібно тільки для результату? А раптом користувач почне там вводити дані? Нічого Страшного не відбудеться, у розрахунках це поле не бере, але все одно неприємно, коли твою програму використовують неправильно. Виділіть компонент Edit3.

На вкладці Properties (властивості) знайдіть властивість ReadOnly (лише для читання), і замість False (брехня), поставте True (істина). Все, тепер користувач не зможе вводити дані в це поле, тільки програма зможе виводити в нього результат.

Збережете, виконайте Run і переконаєтеся в цьому.

Лекція 4. Керуюча конструкція if, цикл for.

Строкові типи даних

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

Найперша таблиця символів, створена для операційної системи MS-DOS, називалася ASCII. Ці символи були 7-мі бітними, як наслідок, таблиця містила максимум 127 символів. Оскільки в одному байті міститься 8 біт, один біт губився даремно. У цій таблиці були свої мовні розширення, тобто, для кожної мови робилася своя така таблиця.

Для операційної системи Windows була розроблена таблиця символів ANSI, яка використовується донині. Ця таблиця використовує 8-мі бітні символи, тобто містить 256 символів, від 0 до 255. В Delphi така таблиця використовується, як основна. Більша кількість символів дозволило вставити таблицю не тільки основні символи, але і цифр, знаків пунктуації та спеціальні символи. Ми будемо працювати, в основному, з цієї таблиці. Для того, щоб задовольнити потреби користувачів інших мов, була створена таблиця UNICODE. Ця таблиця використовує 16 біт, і в неї поміщається від 0 до 65 535 символів. Ця таблиця, починаючи з Windows 2000, використовується все більш широко, і коли-небудь стане стандартом, але поки що вона зустрічається набагато рідше, ніж ANSI. Є наступні строкові типи даних:

ShortString - короткий рядок з ANSI символів. Кількість символів може бути від 0 до 255. Іншими словами, рядок довжиною понад 255 символів в ShortString записати не можна.

LongString - довга рядок ANSI символів. Довжина рядка тут майже не обмежена, в одну змінну такого типу можна записати текстовий файл з романом «Війна і мир». Цей тип використовується за замовчуванням, тобто, коли ми вказуємо тип String, мається на увазі саме цей тип даних. З ним нам найчастіше і доведеться працювати.

WideString - довга рядок символів UNICODE. Від LongString відрізняється тільки тим, що використовує іншу, більш розширену таблицю символів.

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

Символьні типи даних

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

AnsiChar - символ ANSI таблиці. Використовується за замовчуванням, тобто, коли ми вказуємо тип Char, маємо на увазі саме цей тип.

WideChar - символ UNICODE таблиці. Різниця між ними така ж, як і у рядків цих типів.

Як і у випадку з рядками, програміст зазвичай оголошує тип Char, що відповідає типу AnsiChar.

Логічний тип даних

Логічний тип даних використовується в умовних виразах. Він необхідний для створення логіки програми. Умовне вираз перевіряє - чи відповідає дійсності заданим критеріям? Якщо відповідає, то вираз повертає результат True (Істина). Якщо не відповідає, то повертається False (Брехня). Таким чином, логічний тип даних може мати тільки одне з двох цих значень. Boolean - логічний тип даних.

У таблиці 4.1 наведені операнди, за допомогою яких формують логічні вирази:

Таблиця 4.1. Логічні операнди

Логічнаяоперація

Опис

Логічнаяоперація

Опис

=

Дорівнює

>=

Більше чидорівнює

>

Більше

<=

Меньше чидорівнює

<

Меньше

<>

Не дорівнює

= =

Точне дорівнює

Припустимо, у нас є два числа, і потрібно перевірити їх на рівність. Ці числа зберігаються в змінних цілого типу a і b. Тоді вираз порівняння буде виглядати так:

a = b;

Якщо в обох змінних зберігається одне і те ж значення, то результатом такого порівняння буде True, інакше - False.

Begin .. end

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

Begin //блок коду end;

Зверніть увагу, що після слова Begin крапка з комою не ставиться. Ці програмні дужки обов'язкові для кожної процедури або функції, навіть якщо вони містять тільки одну команду. Однак ці ж дужки часто застосовуються в керуючих конструкціях або циклах. Цикли, як і керуючі конструкції, працюють тільки з одним оператором (командою). А що, якщо в цьому місці потрібно використовувати більше одного оператора? Тут на допомогу приходять ці самі програмні дужки. Весь блок коду, скільки б команд там не було, укладений між Begin і End сприймається, як один оператор. Ми не раз будемо використовувати ці дужки.

Цикл for

Ще один потужний інструмент в Delphi - цикли. Ці цикли виконують оператор або блок операторів вказану кількість разів. Синтаксис циклу for наступний: for лічильник := нач_значение to кон_значение do оператор;

У розширеному варіанті синтаксис такий:

forсчетчик := нач_значение toкон_значение dobegin

оператор 1;

оператор 2;

оператор операторn;

end;

Тут:лічильник - мінлива будь-якого цілого типу; нач_значение - початкове значення лічильника; кон_значение - остаточне значення лічильника.

Як лічильників використовують зазвичай цілі змінні. Щоб не гаяти оперативну пам'ять, лічильників призначають тип Byte або Word, залежно від того, яке значення може виявитися у кінцевого значення.

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

Давайте розглянемо цикл for на прикладі. Нехай нам потрібно перевести температуру від 0 до 100 градусів за шкалою Цельсія в шкалу Фаренгейта. Правила тут прості: потрібно взяти температуру по Цельсієм, помножити її на 9/5 і до результату додати 32. Сам результат потрібно буде програмно додати в компонент Memo у вигляді рядка:

«x градусів за Цельсієм = y градусів за Фаренгейтом»

Створіть новий додаток.

Відразу ж властивості Name форми вкажіть ім'я fName. У властивості Caption напишіть «Переклад температур з Цельсія в Фаренгейты». Збережете в нову папку.

У верхню частину вікна помістіть компонент Memo і у властивості Lines видаліть з нього весь текст. Розтягніть Memo за формою, як на малюнку 4.1:

Рис. 4.1. Зовнішній вигляд програми

Нижче Memo додайте кнопку Button, у властивості Caption якої вкажіть «Розрахунок температур». Тепер створимо обробник натискання на кнопку, двічі клацнувши по ній. Процедура виглядає так:

procedure TfMain.Button1Click(Sender: TObject); var

i : Byte; //лічильник

begin fori := 0 to 100 do //робимо від 0 до 100

Memo1.Lines.Add(IntToStr(i) + ' градусів Цельсія = ' +

FloatToStr(CelToFar(i)) + ' Фаренгейта end');

Тут слід звернути увагу на останній оператор. Оператор Memo1.Lines.Add('Рядок'); додає рядок ‘Рядок’ в компонент Memo. При цьому, як рядка, ми використовували складне вираз, формує рядок з різних частин. Розглянемо кожну частину докладно.

Лекція 5. Властивості Властивості форми

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

Borderlcons - властивість визначає, які кнопки повинні бути у отриманого вікна. Складне властивість, яку можна відкрити, натиснувши за знаком «+» ліворуч від назви. Має тільки 4 значення, кожне з яких може бути True, тобто кнопка є, і False, тобто, її немає.

> BiSystemMenu визначає, чи буде у форми системне меню, яке показано у вигляді іконки зліва на заголовку вікна. Крім того, чи будуть там інші кнопки заголовка. > BiMinimize визначає кнопку мінімізації (згортання) вікна. При цьому False не прибирає саму кнопку, а тільки робить її неактивною.

> BiMaximize точно також визначає кнопку розгортання вікна.

> BiHelp - кнопка допомоги у вигляді знаку питання. Не здасться у звичайного вигляду форми, навіть якщо поставити в True.

BorderStyle - спадне властивість форми, визначає її загальний вигляд. Може бути: > BsSizeable - звичайне вікно. Встановлено за замовчуванням. Стандартне вікно, яке може змінювати розміри.

>BsDialog - вікно у формі діалогу, має тільки кнопку «закрити».

> BsNone - вікно взагалі без волани і без заголовка вікна.

>BsSingle - відрізняється від звичайного вікна тим, що у нього не можна змінити розміри.

>BsSizeToolWin - вікно з тонкою оборкою. Особливо це помітно у заголовку вікна. > BsToolWindow - таке ж, як попередній, але у цього вікна не можна змінювати розміри.

BorderWidth - ширина волани вікна. За умовчанням встановлено 0.

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

Cursor - вигляд вказівника миші. Ви вибираєте, як буде виглядати покажчик при наведенні на форму.Font - вибір шрифту за замовчуванням. Іншими словами, якщо Ви зміните шрифт, то всі компоненти, що встановлюються на форму, за замовчуванням приймуть його.Height - висота вікна. Зверніть увагу, що коли ви мишею змінюєте розмір вікна, це властивість автоматично змінює значення.Icon - іконка у заголовку вікна. Якщо двічі клацнути по цій властивості, вийде вікно завантаження інший іконки. За замовчуванням встановлена стандартна іконка Delphi 7, але можна зробити і свою власну. Найчастіше використовують колекції ікон, скачали їх Інтернет. Але якщо ви відчуваєте в собі талант художника, можете спробувати зробити іконку для свого проекту самостійно. Для цього використовуйте вбудовану утиліту Image Editor, ярлик якої знаходиться там же, де Delphi. Виберіть команду «Файл " - New - Icon file», і малюйте на здоров'я!

Name - назва компоненту форми. Це властивість разом з властивістю Caption ми вже розглядали, так що просто згадаємо, що Name головною форми бажано завжди вказувати однаково, наприклад, fMain Position - розташування вікна. Досить важливе спадне властивість! Воно має кілька значень:

  • PoDefault - Windows сам вирішуватиме, де розташувати ваше вікно на екрані, і які у нього будуть розміри.

  • PoDefaultPosOnly - Windows вирішує, де буде вікно, а розміри його будуть такими ж, як ви їх встановили.

  • PoDefaultSizeOnly - позиція залишається, як ви вказали, але Windows вирішує, які у вікна будуть розміри.

  • PoDesigned - це значення за замовчуванням. І позиція, і розміри залишаються такими, як ви їх створили.

  • PoDesktopCenter - вибирайте цей варіант, якщо бажаєте, щоб вікно завжди виходило по центру робочого столу.

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

  • PoOwnerFormCenter - це значення змусить дочірнє вікно з'являтися по центру того вікна, з якого воно викликане.

  • PoScreenCenter - вікно з'являється по центру екрана. Майже те ж саме, що і PoDesktopCenter.

  • Width - ширина вікна. Як і висота, це властивість змінює своє значення, коли ви змінюєте розмір форми.

  • WindowState - стан вікна після запуску. Має три значення:

  • WsNormal - за замовчуванням. Вікно показується у нормальному стані.

  • WsMaximized - вікно з'являється в розгорнутому вигляді.

  • WsMinimized - вікно з'являється у згорнутому вигляді.

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

Властивості кнопки TButton

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

Name - це властивість нам цілком знайоме, воно вказує ім'я цього компонента. Зазвичай ми змінювали Name тільки у форми, але надалі привчайтеся змінювати його у всіх компонентів. Коли у вас будуть складні форми з безліччю кнопок, дуже складно буде визначити в редакторі коду, що робить кнопка Button 1 або Button12. Тому буде краще, якщо ви привчитеся давати кнопок осмислені назви. Приміром, у редакторі текстів ми встановлювали 3 кнопки: Завантажити, Зберегти і Очистити. Отже, було б правильним змінити назви кнопок на bLoad, bSave і bClear. Перша буква b підкаже нам, що це кнопка, а назву після цієї букви скаже, що кнопка повинна робити. Привчайтеся відразу до гарного стилю програмування, якщо не хочете мати неохайний код, в якому легко заплутатися. Якщо Вам не подобаються правила, що форму ми починаємо з букви f, а кнопку з букви b - подумайте свої правила, але надалі завжди дотримуйтесь їх!

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

Top - це положення кнопки від верхньої межі форми. Працює також, як Left, але рухає кнопку по вертикалі.

Інструкція множинного вибору case

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

case of Селектор

значення 1 : begin

Інструкції 1 end; значення 2 : begin

Інструкції 2 end; значення n : begin

Інструкції n

end

elsebegin

Інструкції інакше end;

Тут «Селектор» - це мінлива цілого типу або символьного типу, або вираз, який повертає ціле число або букву. Блок else не є обов'язковим. У випадку, якщо інструкція містить тільки один оператор використовувати програмні дужки begin .. end необов'язково. Прикладзастосування case:

case i of

1 : ShowMessage('i = 1');

2 : ShowMessage('i = 2');

3 : ShowMessage('i = 3');

4 : ShowMessage('i = 4');

else : ShowMessage ('i недорівнює 1, 2, 3 або 4'); end;

Жартівлива програма

Тепер ми можемо написати серйозну програму з формою і кнопкою, де користувач ні за що на світі не зможе натиснути на кнопку миші, тому що кнопка буде втікати від вказівника миші. Ця проста програма була описана в одному з номерів журналу «Хакер», а також у книзі М.Фленова «Біблія Delphi». Вона найкраще показує, яким чином можна програмним способом змінювати властивості компонентів. Як кнопка буде тікати? За допомогою програмного зміни властивостей Left та Top! Однак, щоб зрозуміти код програми від початку до кінця, познайомимося з новою функцією. Функція Random() повертає випадкове число. Цю функцію ще називають генератором випадкових чисел. Синтаксис функції дуже простий:

Random( Integer ) : Integer;

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

Random(5) буде повертати у випадковому порядку числа від 0 до 4 включно. Тобто, повертає значення буде:

0 <= возвращаемое_значение < исходное_число.

Наша кнопка повинна тікати від вказівника миші хаотично, непередбачувано, для цього буде потрібно функція Random().

Створіть форму середнього розміру і киньте на неї лише одну кнопку. Для більшого ефекту у властивості Caption форми напишіть: «Виграй приз!». А на кнопці напишіть «Натисни мене».

Якою б швидкої не була реакція користувача, вона ніяк не зрівнятися зі швидкістю, з якою процесор обробляє інструкції. А процесор обробляє мільйони інструкцій в секунду! Тому користувач ніколи не зможе натиснути на кнопку миші, але зможе це зробити за допомогою клавіші <Enter> на клавіатурі. Врахуємо це. Створимо обробник натискання кнопки і там напишемо тільки один рядок:

ShowMessage('Enter натискати нечесно, користуйся мишкою!');

Тепер залишилося написати код втікання миші. Виділіть кнопку на формі. В інспекторі об'єктів відкрийте вкладку Events (події). Нас цікавить подія OnMouseMove, яке відбувається всякий раз, коли вказівник миші виявляється над кнопкою. Двічі клацніть на події, і у редакторі коду введіть наступне:

procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

var index : Integer;

begin

index := random(4); //присвоюємо змінної випадкове значення від 0 до 3

//в залежності від значення змінної, вибираємо дію

caseindexof

0: Button1.Left := Button1.Left + Button1.Width; //рухаємо кнопку вправо, на значення

//ширини кнопки 1: Button1.Left := Button1.Left - Button1.Width; //кнопка вліво, на значення ширини 2: Button1.Top := Button1.Top + Button1.Height; //кнопка вниз, на значення висоти 3: Button1.Top := Button1.Top - Button1.Height; //кнопка вгору, на значення висоти

end; //case

{Якщо кнопка вийшла за межі форми, повернемо її в положення 0} ifButton1.Left< 0 thenButton1.Left := 0; ifButton1.Top< 0 thenButton1.Top := 0;

if (Button1.Left + Button1.Width) >Form1.WidththenButton1.Left := Form1.Width - Button1.Width;

if (Button1.Top + Button1.Height) >Form1.HeightthenButton1.Top := Form1.Height - Button1.Height;

end;

Розберемо цей код. На самому початку в змінну index ми записуємо випадкове число від 0 до 3. Це нам потрібно, щоб знати, куди рухати кнопку, адже рухати її можна вліво, вправо, вгору або вниз. Залежно від того, яке значення ми отримали, програма вибере напрямок переміщення кнопки. Для цього використовується конструкція case. Якщо у змінній у нас число 0, кнопка буде рухатися вправо. Як це відбувається? Властивості Left (ліва позиція) кнопки ми надаємо нове значення - ліву позицію цієї кнопки, плюс її ширину. Іншими словами, кнопка зрушиться вправо на відстань, рівне ширині цієї кнопки. Таким же чином ми зсуває кнопку вліво, якщо змінної index буде присвоєно число 1. Тільки тут ми не додаємо, а віднімаємо ширину.

Майже таким же чином кнопка тікає вгору або вниз, але тут ми використовуємо інші властивості - Top (відстань від верхньої межі вікна до кнопки) і Height (висота кнопки в пікселях). Відповідно, якщо ми додаємо висоту до верхньої межі, кнопка тікає вниз, і навпаки.

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

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

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

Інструкція (цикл) WHILE

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

Синтаксис інструкції такий:

while умова do інструкція;

або розширений варіант:

while умова dobegin

інструкція 1;

інструкція 2;

... інструкція n; end;

Тут умова - мінлива або вираз логічного типу. Спочатку обчислюється умова. Якщо умова помилково (False), то цикл не виконується і відразу закінчує роботу. Якщо умова вірно (True), то цикл виконує інструкції, потім знову повертається до умові. Якщо умова знову повертає True, цикл виконується ще раз, і так до тих пір, поки умова не поверне False. Будьте обережні з цим циклом! Не включайте туди умова, яка ніколи не стане False. Комп'ютер у такому разі «зациклиться», тобто зависне. Зазвичай для цього всередину циклу поміщають лічильник - змінну цілого типу. Тільки на відміну від циклу for, тут мінлива не збільшує своє значення автоматично, за цим повинен стежити сам програміст. Прикладзастосуванняінструкції:

i := 1;

while i < 10 do begin

ShowMessage('Кількістьодно ' + IntToStr(i));

i := i + 1;

end;

У цьому простому прикладі ми цілої змінної i присвоюємо значення 1. Потім виконуємо цикл while до тих пір, поки i не стане більше або дорівнює 10. Якщо б ми всередині циклу не вказали «i := i + 1;», то цього ніколи б не відбулося, і ми зациклили б програму! Спробуйте виконати цей приклад у новому проекті, прив'язавши код до обробки натискання кнопки. У подальшій практиці Вам не раз доведеться використовувати цей цикл з куди більш корисними прикладами.

Лекція 6. ООП - ОБ'ЄКТНО-ОРІЄНТОВАНЕ ПРОГРАМУВАННЯ Об'єкт

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

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

Подіями - події користувацьких дій, наприклад, користувач натиснув на кнопку, покажчик миші опинився над кнопкою, і т.п.

Методами - що забезпечують роботу кнопки, наприклад промальовування кнопки в натиснутому і не натиснутому вигляді, промальовування фокусу (тобто, фокус вводу на кнопку).

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

>• Властивості - це змінні, які впливають на стан об'єкта. Наприклад, ширина, висота, положення кнопки на формі або напис на ній.

> Методи - це ті ж процедури і функції, тобто це те, що об'єкт вміє робити (обчислювати). Наприклад, об'єкт може мати процедуру для виведення якого-то тексту на екран. Кнопка при натисканні змінює форму - це метод кнопки, процедура промальовування виду натиснутою і не кнопки натиснутою.

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

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

Компоненти - це більш досконалі об'єкти. Тобто, це об'єкти, з якими можна працювати візуально. Справедливості заради слід зазначити, що існують і не візуальні компоненти, наприклад, діалоги, з якими нам скоро належить познайомитися. Не слід плутати поняття «об'єкт» і «компонент».

Кожен компонент - це об'єкт, але не кожен об'єкт є компонентом. Уявімо собі абстрагований приклад. Припустимо, у нас на панелі компонентів є компонент ТЧел, який являє собою усередненого людини. Якщо ми мишкою клацнемо з цього компоненту, а потім клацнемо за формою, то ми створимо окремий, автономний об'єкт цього компонента, який вже володіє всіма властивостями, методами і подіями, притаманними кожній людині. Такий автономний об'єкт називається примірником об'єкта.

Як у будь-якого об'єкта, у нього є властивість Name - назва компоненту, то ім'я, по якому ми будемо надалі звертатися до цього об'єкту. Delphi за замовчуванням присвоїть йому текст «Чол1».

Якщо ми встановимо на форму ще один такий компонент, то буде створено ще один автономний об'єкт (екземпляр), у якого властивість Name буде містити рядок «Чол2». Отже, властивість Name - це мінлива строкового типу, що належить будь-якого об'єкта, і є ідентифікатором (опознавателем), за яким до цього об'єкту потрібно звертатися.

Далі, у нашого уявного об'єкта є й інші властивості. Наприклад, властивості Ім'я, Прізвище, по Батькові. Це також строкові змінні, що належать цьому об'єкту. Ми можемо вписати в них потрібний текст програмно:

Чол1.Імя := 'Іван';

Чол1.По-батькові := 'Іванович';

Чол1.Прізвище := 'Іванов';

Зверніть увагу, що властивість Name містить назву об'єкта, по якому ми до цього об'єкту звертаємося. Якщо б ми змінили у властивості Name Чел1 на Людей, то код виглядав би інакше:

Чол1.Імя := 'Іван';

Точно також, ці властивості ми можемо змінювати в Інспекторі об'єктів, у момент створення програми. Так, ми міняли властивості Caption у кнопок, виводячи на них нам потрібний текст. А переміщаючи кнопку на потрібну позицію, ми тим самим міняли властивості Left та Top.

Далі, цей об'єкт має не тільки стічні, але й інші типи властивостей змінних. Наприклад, вік (в роках) і зростання (в сантиметрах) - це будуть змінні цілого типу

Чол1.Вік := 30; Чол1.Зріст := 180;

Об'єкт може мати і символьне змінну, наприклад, властивість Стать (м - чоловіча, ж - жіночий):

Чол1.Стать := 'м';

Також такий об'єкт може мати і логічний тип даних, наприклад, Військовозобов'язаний, тобто був у армії чи ні:

Чол1. Військовозобов'язаний:= True;

Дуже часто буває, що в різних компонентах ми вказуємо в інспекторі об'єктів початкові значення, як би за замовчуванням, а потім під час роботи програми міняємо їх на потрібні. У програмі з убегающей кнопкою, ми задали кнопці початкове положення, а потім, під час роботи програми, ми змінювали властивості Left та Top. А коли користувач вводить текст у компонент Edit, програмно змінювалося його властивість Text.

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

Повернемося до реальних компонентів. Візьмемо компонент TEdit. Якщо ми кинемо на форму такий компонент, то Delphi автоматично встановить властивість Name рівним рядку Edit1. Надалі ми будемо звертатися до цього об'єкту з цього імені. Якщо ж ми в Інспекторі об'єктів змінимо властивість Name з Edit1 на, скажімо, MyEdit, то доведеться звертатися вже не до Edit1, а до MyEdit. Припустимо, ми змінили це властивість. Не забуваємо, що властивість Name - мінлива типу рядок.

Далі, в компоненті TEdit нас цікавлять ще кілька властивостей. Це властивості Left та Top, які мають цілий тип, і забезпечують положення компонента на формі. Властивість Left вказує у точках відстань від лівої межі форми до компоненту, а властивість Top - таке ж відстань від верхньої межі. Ще є властивості Width (ширина компонента) і Height (висота компонента). Це теж цілі типи, вони вказують значення в пікселях.

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

MyEdit.Text := ";

Потім, під час виконання програми, користувач вводить якийсь текст у наш Edit. Нам потрібно обробити цей текст, і отримати до нього доступ ми можемо, вказавши ім'я потрібного об'єкта і його властивість:

s := MyEdit.Text;

У даному прикладі ми привласнили строкової змінної s той текст, який в даний момент зберігався в полі нашого компонента Edit.

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

Ми маємо можливість програмно змінити текст у цьому об'єкті, і в даному випадку будемо вказувати змінну - властивість Text: MyEdit.Text := 'текст';

Тепер наш об'єкт буде відображати рядок з новим текстом. Крім того, ми програмно можемо змінювати та інші властивості. Наприклад, властивість Left - положення від лівої межі форми. Ми можемо вказати:

MyEdit.Left := MyEdit.Left - 5;

Якщо ми вкажемо такий текст, наприклад, у процедурі обробки натискання кнопки, то кожен раз, коли ми натискаємо на кнопку, об'єкт MyEdit буде рухатися вліво на 5 пікселів. Спробуйте самі! Створіть новий додаток, встановіть на форму компонент TEdit і кнопку. Якщо Ви не змінили властивість Name, доведеться звертатися до об'єкту по імені, яке за замовчуванням присвоїла йому Delphi:

Edit1.Left := Edit1.Left - 5;

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

Edit1.Name := 'MyEdit';

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

Не хвилюйтеся, нічого страшного не сталося. Просто виберіть у меню команду Run - Program Reset. Це змусить програму достроково припинити виконання і закритися.

Не забувайте ще ось про що: не у всіх компонентів, які виводять текст на екран, є властивість строкового типу Text. Наприклад, у компонента TLabel такою властивістю є Caption, і якщо ми хочемо в інспекторі об'єктів вписати в об'єкт якийсь текст, вписувати його потрібно саме в властивість Caption. Точно також, Якщо ми бажаємо програмно змінити текст в об'єкті Label1, то робимо присвоєння нового тексту його властивості Caption:

Label1.Caption := 'текст';

Однак, є об'єкти і складніша. Візьмемо, приміром, TMemo. У нього немає властивості Text в інспекторі об'єктів, однак це властивість є програмно. Мінлива - властивість Text об'єкта Memo1 містить весь текст, всі рядки, які перебувають наразі в компоненті. Однак набагато частіше застосовують властивість Lines. Це властивість вже не проста символьна змінна, а цілий масив рядків, де кожен елемент містить окремий рядок тексту. Можна сказати, що Lines - це об'єкт в об'єкті, який також має свої методи, тобто функції і процедури. Найчастіше використовують методи SaveToFile() і LoadFromFile(), які відповідно, зберігають текст у файл і читають текст з файлу. Властивість Lines має тип TStrings, тобто не просто рядок, а набір рядків.

Багато компоненти мають властивості такого типу. Наприклад, компонент TListBox має властивість Items, яке належить до того ж типу TStrings, отже, має такі ж методи, як і Lines у компонента TMemo. Це означає, що викликавши потрібний метод, ми можемо, наприклад, вважати текст з файлу і в Memo, і в Lіstbox:

Memo1.Lines.LoadFromFile('myfile.txt');

ListBox1.Items.LoadFromFile('myfile.txt');

Ви неодноразово будете зустрічатися з властивостями типу TStrings в різних компонентах. Це дуже потужний інструмент, і потрібно вчитися користуватися ним.

Події

Події - це процедури, які виконуються всякий раз, коли це подія відбувається. Наприклад, подія OnChange компонента Edit відбувається всякий раз, коли змінюється текст у полі вводу. Події знаходяться на вкладці Events Інспектора об'єктів. Якщо ми нічого не зробимо, то при настанні цієї події нічого і не відбудеться. Однак, якщо ми двічі клацнемо мишею по цій події - створиться процедура обробки цієї події. І той програмний код, який ми введемо, буде виконуватися всякий раз, коли це подія відбувається.

Подія OnChange застосовують досить часто, коли потрібно перевірити чи правильні дані користувач вводить. Хороша новина - більшість подій (а також властивостей і методів), у більшості компонентів однакові. Наприклад, практично будь-який компонент для введення користувачем тексту має подія OnChane. Чи застосовуєте ви Edit або Memo, це подія працює однаково.

Лекція 7. Вивчаємо компоненти Panel, GroupBox, RagioGroup,

CheckBox

Компонент Panel (Панель)

Компонент Panel знаходиться на вкладці Standard і застосовується для поліпшення зовнішнього вигляду форми, а також для угруповання декількох компонентів. Цей компонент по своїм властивостям трохи нагадує форму. Якщо встановити кілька інших компонентів на Panel, то при зсуві панелі будуть зміщуватися і компоненти, встановлені на ній.

Вивчимо цей компонент на практиці. Створіть новий проект, і встановіть на форму один компонент Panel. За замовчуванням, властивості Caption панелі присвоюється те ж ім'я, що і властивості Name, тобто прямо по центру панелі виходить текст «Panel 1». Нас це не влаштовує. Очистимо властивість Caption панелі - просто видаліть цей текст, нічого туди не вписуючи.

Розберемо інші корисні властивості цього компонента. Властивості сімейства Bevel відповідають за зовнішній вигляд компонентів:

Bevellner і BevelOuter мають однакові значення, і відповідають за те, який панель буде виглядати - опуклої або увігнутою. Спробуйте змінювати значення цих властивостей, і Ви все зрозумієте.

BevelWidth вказує ширину волани панелі. Спробуйте змінити значення на 5. Панель виглядає екзотично, але не професійно, краще у цього властивості залишати значення за замовчуванням.

Ще одна дуже важлива властивість - Align (Вирівнювання). Це властивість часто використовують не тільки у панелей, але й у багатьох інших компонентів. Align має кілька значень:

> AlBottom - вказує, що панель буде займати весь низ форми. Коли розміри форми змінюються, змінюється і розмір панелі, але вона як і раніше займає весь низ.

> AlClient - вказує, що панель займає весь простір форми. Якщо ви встановили панель, і розтягнули її по всьому вершині, а потім встановили ще одну панель і вказали значення alClient, то друга панель займе все інше місце.

> AlCustom - вказує користувача настройки. При зміні розмірів форми така панель залишиться, як при розробці дизайну.

> AlLeft - займає всю ліву частину форми.

> AINone - вирівнювання немає. Працює практично як AlCuctom.

> AlRight - займає всю праву частину форми.

> AlTop - панель витягується у верхній частині форми.

Раніше ми створювали простий редактор текстів. Поліпшимо цей приклад. Вкажіть у властивості Height (висота) панелі значення 40. Властивість Top встановіть у 0. Тим самим ми притиснули панель до самого верху форми. Властивості Align присвоюємо значення alTop, розтягуючи панель по всьому верхнього краю. Тепер, якщо користувач стане змінювати розміри форми, стискаючи вікно або навпаки, розтягуючи, панель все одно буде займати весь верх. Встановлюючи на цю панель кнопки, ми отримаємо типову панель інструментів. Так і зробимо: встановіть на панель три кнопки, одну поряд з іншого. На кнопках повинен бути текст: «Зберегти», «Завантажити» і «Очистити».

На решту внизу місце поміщаємо компонент Memo, двічі клацніть по властивості Lines, щоб викликати редактор тексту, і видаляємо з Memo весь текст. Властивості Align компонента Memo присвоїмо значення alClient, щоб розтягнути Memo по всьому залишився місцем. Не забудьте властивості ScrollBars присвоїти значення ssVertical - це потрібно для того, щоб текст автоматично переходити на новий рядок, і ми мали можливість прокручувати його.

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

Компоненти GroupBox і CheckBox

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

Створіть новий додаток. Ми зробимо корисну програму, що змінює вигляд форми залежно від налаштувань. На форму встановіть компонент GroupBox, привласнивши його властивостям Left та Top значення 6, щоб притиснути його до верхнього лівого краю вікна. У властивості Caption цього компонента напишіть текст «BorderIcons». Оскільки обрамлення компонента впритул підходить до тексту - заголовку, з професійної точки зору буде незайвим додати пару пробілів перед текстом, і стільки ж після нього.

Ми вже знаємо, що BorderIcons - це властивість форми, програмуючий її зовнішній вигляд. Ця властивість має 4 значення, кожне з яких можна увімкнути або вимкнути. Таким чином, нам потрібно 4 класичних «прапорець», в які можна буде поставити «галочку» або прибрати її. Роль таких прапорців виконує компонент CheckBox. Встановіть 4 CheckBox прямо на панель GroupBox, один над іншим:

Рис. 7.1. Зовнішній вигляд програми

Змініть властивість Caption цих компонентів, написавши там, відповідно, «biSystemMenu», «biMinimize», «biMaximize» і «biHelp». Властивість Checked компонента CheckBox показує чи включений компонент, іншими словами, чи встановлено в ньому «галочка». У форми за замовчуванням перші три значення включені, також зробимо і тут - у перших трьох компонентів CheckBox встановіть властивість Checked в True.

Компонент RadioGroup

Цей компонент також має вигляд панелі і призначений для угрупування так званих радіокнопок. Включеної може бути лише одна така радіокнопка. На малюнку 7.1 в правій частині форми ви бачите таку панель з встановленими радіокнопками. Додайте компонент RadioGroup на форму, у властивості Caption встановіть текст «BorderStyle», не забуваючи про прогалини до і після тексту. Встановлювати на цій панелі перемикачі значно легше, ніж кнопки CheckBox. Виділіть цю панель і двічі клацніть по її властивості Items. Відкриється текстовий редактор, такий же, як у Memo. У цьому редакторі потрібно написати назви кнопок, кожну кнопку обов'язково потрібно писати на окремому рядку. Напишіть такі кнопки:

bsSizeable

bsDialog

bsNone

bsSingle

bsSizeToolWin

bsToolWindow

Як тільки ви натиснете кнопку «ОК» і закриєте редактор, на панелі RadioGroup з'являться описані кнопки. Жодна з них не має включеного виду. Ми вже знаємо, що можна включити тільки одну таку кнопку зі списку. Компонент RadioGroup має властивість ItemIndex, яке вказує, яка кнопка в даний момент включена. За замовчуванням, ItemIndex дорівнює-1. Оскільки нумерація кнопок починається з нуля, значення -1 означає, що ні одна кнопка не включена. Встановіть значення 0, включивши тим самим першу кнопку (на формі однойменне параметр увімкнено за замовчуванням).

Нижче встановіть кнопку, написавши на ній слово «Застосувати». Все, з дизайном закінчено, переходимо до програмування кнопки. Якщо ви ще не зберегли проект в нову папку, зробіть це зараз. Властивості Name форми, як зазвичай, дайте ім'я fMain, модулю - просто Main, усього проекту в цілому - FormViewer.

Повернемося до кнопки. Двічі клацніть по ній, створивши процедуру обробки натискання кнопки.

Процедурамаєнаступнийвигляд:

procedure TfMain.Button1Click(Sender: TObject); begin

//обробляємокомпонент BorderIcons

if CheckBox1.Checked then fMain.BorderIcons := fMain.BorderIcons + [biSystemMenu]

else fMain.BorderIcons := fMain.BorderIcons - [biSystemMenu];

if CheckBox2.Checked then fMain.BorderIcons := fMain.BorderIcons + [biMinimize] else fMain.BorderIcons := fMain.BorderIcons - [biMinimize]; if CheckBox3.Checked then fMain.BorderIcons := fMain.BorderIcons + [biMaximize] else fMain.BorderIcons := fMain.BorderIcons - [biMaximize]; if CheckBox4.Checked then fMain.BorderIcons := fMain.BorderIcons + [biHelp] else fMain.BorderIcons := fMain.BorderIcons - [biHelp]; //обробляємокомпонент BorderStyle case of RadioGroup1.ItemIndex

0 : fMain.BorderStyle := bsSizeable;

1 : fMain.BorderStyle := bsDialog;

2 : fMain.BorderStyle := bsNone;

3 : fMain.BorderStyle := bsSingle;

4 : fMain.BorderStyle := bsSizeToolWin;

5 : fMain.BorderStyle := bsToolWindow; end; //case

end;

Розберемося з кодом. Спочатку ми обробляємо перший прапорець CheckBox:

if CheckBox1.Checked then fMain.BorderIcons := fMain.BorderIcons + [biSystemMenu] else fMain.BorderIcons := fMain.BorderIcons - [biSystemMenu];

Якщо цей параметр увімкнено, його властивість Checked поверне Істину, і тоді до властивості форми BorderIcons буде додана константа [biSystemMenu]. Про константи, у тому числі і вбудованих, ми будемо говорити пізніше. Поки що важливо одне - якщо ми додаємо цю константу, то включаємо це значення в властивість BorderIcons.

Приклад взятий з вбудованого довідника Delphi. Поставте курсор блимає всередині слова BorderIcons і натисніть <Ctrl + F1>. Вийде контекстний довідник з цією командою. Якщо вам буде запропоновано вибрати між CLX і VCL, вибирайте останню (Visual Components Library - Бібліотека візуальних компонентів). Далі клацніть по посиланню «Delphi example» (Приклад для Delphi). У показаному В довідці прикладі відключається кнопка «Розгорнути вікно».

Таким же чином, ми обробляємо решта три компоненти CheckBox. Далі йде обробка панелі RadioGroup. Оскільки тільки одна кнопка може бути включена, то властивість ItemIndex цієї панелі може мати тільки 6 значень, за кількістю кнопок: від 0 до 5.

Тут найзручніше використовувати конструкцію case. В залежності від значення ItemIndex ми надаємо однойменне включеної кнопці значення властивості BorderStyle форми. От і все.

Збережіть приклад, зберіть і подивіться, як працює програма. Залежно від обраних значень після натискання кнопки «Застосувати» змінюється зовнішній вигляд форми. У деяких випадках її розміри можна змінювати, розсовуючи мишею, в деяких - ні. У випадку, якщо BorderStyle дорівнює значенню bsNone, пропадає і оборка вікна, і верхня системна рядок форми. Поекспериментуйте. Ця утиліта може виявитися корисною надалі, якщо ви бажаєте заздалегідь подивитися, які налаштування вибрати, щоб вікно вашої програми було саме так, як ви задумали. Наприклад, щоб не можна було міняти його розміри, щоб були відсутні кнопки «Згорнути» і «Розгорнути» і т.п.

Лекція 8. Меню

Властивості Enabled і Visible

Ці властивості присутні практично у всіх візуальних компонентів і дозволяють використовувати цікаві прийоми програмування.

Відкрийте проект з редактором тексту з минулій лекції. У вас там є три кнопки «Зберегти», «Завантажити» і «Очистити». Давайте припустимо, що користувач набрав якийсь важливий текст і зберіг його. Наступного дня він знову завантажив ваш редактор, але помилково замість кнопки «Завантажити» він натиснув кнопку «Зберегти». Що станеться? Ніякого тексту в даний момент компонент Memo не містить. Якщо буде виконана команда

Memo1.Lines.SaveToFile('MyFile.txt');

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

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

Властивість Enabled відповідає за доступність компонентів. Ця властивість має логічний тип, і може бути або True або False. Виділіть кнопку з написом «Зберегти», знайдіть її властивість Enabled і замість встановленого за замовчуванням значення True, виберіть значення False. На формі не сталося видимих змін, ми не зможемо їх побачити в режимі розробки програми. Однак збережете, зберіть командою Run і подивіться на результат - кнопка «Зберегти» видно на формі, але її напис виходить сірим, неактивним кольором, а неможливо натиснути на кнопку. Тепер у користувача немає можливості натиснути на цю кнопку, значить, він не зробить такої помилки. Але це тільки півсправи, треба все таки в процесі роботи програми йому цю можливість повернути, інакше як він зможе зберегти текст?

В лекції 6 ми обговорювали подія OnChange, яке відбувається всякий раз, коли компонент змінюється. Цим ми і скористаємося. Виділіть компонент Memo, в Інспекторі об'єктів перейдіть на вкладку Events (Події) і знайдіть там подія OnChange. Двічі клацніть по ньому, щоб згенерувати процедуру - обробник цієї події. У цій процедурі запишемо всього лише один рядок:

Button1.Enabled := True;

Таким чином, при зміні компонента Memo (користувач змінив текст), ми робимо доступною кнопку «Зберегти». Якщо ви змінили ім'я кнопки, то замість Button1 вкажіть це ім'я. Тепер користувач може зберегти свої зміни.

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

Button1.Enabled := False;

Відразу, як тільки текст буде збережено, кнопка «Зберегти» знову стане недоступною, поки користувач не зробить чергових змін в тексті.

Також зробіть недоступною цю кнопку після того, як користувач натисне кнопку «Очищення», ця кнопка очищає набраний текст, що саме по собі змушує працювати подія OnChange компонента Memo, однак зберігати порожнечу сенсу немає.

Властивість Visible компонентів працює практично також, як властивість Enabled, тільки замість того, щоб робити компонент недоступним, воно робить його невидимим. Visible також має логічний тип, і може бути або True (компонент бачимо)або False (невидимий). Самостійно змініть всі наведені вище рекомендації, використавши замість властивості Enabled властивість Visible. Подивіться на результат. Приховувати або відключати можна не тільки кнопки, але і взагалі всі видимі частини - редактор Memo, поле Edit, напис Label. Навіть у форми є ці властивості, тому при деякої фантазії ви можете домагатися цілком професійних ефектів.

Головне меню

Будь-яка більш-менш серйозна програма має власне меню. Прийшла пора познайомитися з цим компонентом. Для прикладу знову завантажимо наш редактор текстів. Виділіть всі кнопки на формі і видаліть їх. Також видаліть і панель, на якій ці кнопки були. Потім нам потрібно видалити всі процедури обробки цих кнопок, але тут потрібно проявити обережність - не можна просто взяти і видалити процедуру. Кожна згенерований процедура прописана в коді і вище. Щоб без помилок видалити всі непотрібні останні процедури, слід просто видалити з них той код, який ми писали самі, залишивши «порожню» процедуру - ім'я процедури і рядки begin .. end:

Рис. 8.1. Видалення непотрібних процедур

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

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

Виділіть компонент Memo, і переконайтеся, що в його властивості Align встановлено значення alClient, тобто, Memo розтягнуто на всю форму. На вкладці Standard знайдіть компонент MainMenu (головне меню), і встановіть його на будь-яке місце форми, прямо на компонент Memo. Компонент MainMenu не візуальний, тобто, користувач все одно не буде його бачити.

Будемо створювати меню. Двічі клацніть по MainMenu, щоб викликати редактор меню. Коли редактор відкриється, ви побачите, що перший пункт меню виділений синім кольором. Нехай виділення залишається, перейдіть на властивість Caption і введіть текст «Файл». Натиснувши <Enter>, ви сформуєте у меню команду «Файл», а виділення переміститься направо, до наступної команди. Інший пункт меню ми поки робити не будемо, клацніть мишею трохи нижче команди «Файл», щоб виділити пункт нижче. Виходить, що ми зробили пункт меню «Файл», і зараз робимо підменю цього пункту. Нам потрібні такі команди:

«Зберегти» «Завантажити» «Очистити» «-» «Вихід»

Рис. 8.2. Зовнішній вигляд головного меню редактора

Передостання команда, знак «-» (мінус), формує в меню розділову смугу. Як тільки ви закриєте редактор меню, рядок з головним меню зараз же з'явиться над компонентом Memo. Клацніть один раз по слову «Файл», і відкриється підменю. Клацніть по команді «Зберегти», і буде створена процедура обробки цієї команди. Команда «Зберегти» по -, як і раніше виглядає, як

Memo1.Lines.SaveToFile('MyFile.txt');

Всі інші команди ви вже знаєте, введіть їх аналогічним чином. Команда «Вихід» виглядає так:

Close; //вихід із програми

Спливаюче меню

Спливаюче меню викликається, коли користувач клацає правою кнопкою миші по об'єкту - формі або будь-якого іншого компоненту. Знайдіть на вкладці Standard компонент PopupMenu (спливаюче меню), і також встановіть його поверх компонента Memo. Редактор цього меню викликається таким же чином, як і редактор головного меню. У спливаючому меню зазвичай використовують тільки один головний пункт (хоча можливість зробити подпунткы є). Іншими словами, не потрібно робити пункти меню (Файл, Правка, Вигляд і т.д.) і їх підпункти (Файл -> Створити Файл -> Завантажити і т.д.).

Створіть наступні команди:

«Зберегти» «Завантажити» «Очистити» «-» «Вихід»

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

Тепер спливаюче меню потрібно прив'язати до формі, саме по собі воно працювати не буде. Для цього нам потрібно виділити форму, що є непростим завданням - компонент Memo розтягнутий на все вікно, і немає можливості клацнути по вільного місця форми. Форму найпростіше виділити у вікні Дерева об'єктів (Object TreeView). Якщо у вас в даний момент це вікно закрите, відкрити його можна командою меню View -> Object TreeView, або гарячими клавішами <Shift+Alt+F11>. У цьому вікні можна легко виділити будь-який компонент, у тому числі і форму.

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

Модальні вікна

Модальним називається дочірнє вікно, яке не дає головною формою працювати, поки не закінчена робота цього модального вікна.

Досі ми робили проекти тільки з однією формою. Настав час вивчити многооконные проекти. Скористаємося попереднім прикладом - редактором текстів. Відкрийте цей проект, якщо він закритий.

Щоб створити нове вікно, виберіть команду «Файл " - New - Form». У властивості Caption нової форми напишіть «Про програму», форму назвіть fAbout і збережете. Модуль нової форми, відповідно, назвіть About.

На форму встановіть компонент Label, напишіть у його властивості Caption «Програма: MyNotebook v 1.0»

Нижче встановіть ще один Label. Властивість AutoZize (автоматична зміна розміру) поставте в False, а властивість WordWrap (перенос слів на інший рядок) - у True. Тут напишіть такий текст:

Програма призначена для простого редагування текстів. Програма дозволяє зберігати текст у файл, і читати його з файлу. Файл створюється там же, звідки запущена програма, і має ім'я MyFile.txt.

Нижче встановимо ще один Label. Пишемо в ньому: «Автор: такий-то», можете вказати свої власні прізвище, ім'я та по батькові. Буде чудово, якщо текст цього компонента вийде посередині. Щоб домогтися цього, властивість AutoSize (автоматична зміна розміру) встановіть False, властивість Aligment (вирівнювання тексту) в taCenter.

Нижче встановлюємо кнопку. Пишемо на ній «ОК» і створюємо обробник кнопки для виходу з форми: Close; //закриваємо вікно модальне

Інструкція Close головною форми закриває всю програму, а інструкція Close модального вікна закриває тільки це вікно.

Рис. 8.3. Зовнішній вигляд форми «Про програму»

Можете «пограти» з властивостями Font і Color компонентів, щоб форма виглядала гарнішим.

Подібні вікна зазвичай не мають кнопок «Згорнути» і «Розгорнути», тому у властивості BorderStyle форми fAbout виберіть значення bsDialog. А у властивості Position (позиція форми при її відкритті) виберіть poMainFormCenter, щоб форма з'являлася по центру головного вікна. Зверніть увагу на останнє властивість. Зазвичай для головних вікон програми це властивість встановлюють у poDesktopCenter, щоб форма з'являлася по центру робочого столу, запам'ятайте це на майбутнє.

Тепер, щоб можна було викликати це вікно модально, потрібно «прив'язати» його до головної формі. Зараз в редакторі кодів є дві вкладки - Main і About, це модулі головною форми та форми «Про програму». Перейдіть на вкладку головного вікна та натисніть <F12>, щоб викликати вікно. Виберіть команду «Файл " - Use Unit». Відкриється вікно, де ми побачимо нашу модальную форму. Виділіть її та натисніть OK. Тепер, якщо Ви подивитеся код головною форми, під розділом implementation Ви побачите таку картину:

implementation

uses About;

Delphi вставила інструкцію, при якій головна форма використовує все, що описано в коді модального вікна. Можна було набрати все це вручну, однак, щоб уникнути помилок рекомендується користуватися командою «File - Use Unit». Тоді код точно буде введено без помилок, і саме в те місце, яке потрібно.

Тепер у головній формі знову відкрийте редактор головного меню, двічі клацнувши по компоненту MainMenu. Виділіть пункт праворуч від «Файл», і у властивості Caption напишіть «Довідка». А в пункті нижче напишіть «Про програму»:

Рис. 8.4. Редактор головного меню.

При розробці меню не забувайте про стандарти, прийняті в Windows. Ніхто не забороняє Вам засунути підрозділ «Про програму» Пункт «Файл» або який щось інше. Однак користувач буде шукати його саме в розділі «Довідка». Не змушуйте користувача звикати до інших стандартам, якщо хочете, щоб ваші програми користувалися попитом!

Тепер потрібно написати код виклику модального вікна. Двічі клацніть по підрозділу меню «Про програму», щоб створити процедуру обробки цього підрозділу. Там уведіть інструкцію:

fAbout.ShowModal;

Пам'ятайте, що ми викликаємо форму модального вікна (fAbout), а не його модуль (About), тому потрібно звертатися саме до неї. Збережете, зберіть програму і подивіться результат.

Лекція 9. Масиви і константи Масиви

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

Ім'я змінної : array [діапазон значень] of Тип змінних в масиві;

Приклад: var а : Integer; //змінна цілого типуЪ : array [1..10] ofInteger; //масив цілого типу

begin

Зверніть увагу, що діапазон значень в масиві вказується довільно, між першою і останньою цифрою немає пробілів, але обов'язкові дві точки. Приклад діапазону може бути таким: [5..7], які цифри призначати - вирішувати Вам. Зазвичай у практиці доводиться починати діапазон з 1 або 0, в залежності від ситуації.

Звернення до окремого розділу масиву таке:

а : = 5;

Ь[1] := а;

b[2] := Ь[1]+2;

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

Рис. 9.1. Подання масиву у вигляді таблиці

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

Як вже згадувалося, масиви можуть бути будь-якого типу:

var

а : array [0..3] ofString;

b : array [1..5] of Real;

с : array [10..20] of Boolean;

Обробка масиву

Масиви зручно використовувати там, де доводиться обробляти велику кількість однотипних даних. Візьмемо гіпотетичний приклад: потрібно перевести дані від 1 до 100 американських миль у звичні нам кілометри. Оскільки ми точно знаємо, що у нас буде 100 елементів, можна скористатися масивом, а для його обробки найзручніше використовувати цикл for:

var i : Byte; //лічильник для for

a : Array [1..100] of Real; //масив для отриманих даних

begin

for i := 1 to 100 do

a[i] := i * 1,609;

Що ми маємо в даному прикладі? При першому проході циклу for лічильник i має значення 1, отже, в рядку

a[i] := i * 1,609;

ми звертаємося до першого (a[1]) елементу масиву, і присвоюємо йому значення i, помножене на 1,609 кілометрів. Отже, у елемент масиву a[1], який відповідає одній милі, потрапляє значення 1,609 кілометрів. При другому проході циклу i вже дорівнює 2, значить, у елемент a[2] піде значення 2 * 1,609, тобто 3,218. І так далі, до кінця масиву. Надалі, звернувшись до потрібного елемента масиву, ми зможемо дізнатися, скільки кілометрів буде одно ця кількість миль:

ShowMessage('23 милі = ' + FloatToStr(a[23]) + ' кілометра');

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

for i := 0 to 100 do a[i]

:= i * 1,609;

то отримали б помилку, так як вже при першому проході ми звернулися б до елемента a[0], якого в нашому прикладі не існує.

Константи

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

procedure MyProc;

const

pi = 3.14;

MessageError = 'Текстповідомленняпропомилку';

var a : Integer; b : String;

begin

... end;

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

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

Пройдений матеріал на практиці.

Створимо проект, що використовує всі нові можливості. Створіть новий проект, перейменуйте форму в fMain, а у властивості Caption вкажіть «Випадкові числа». Збережіть в нову папку. Проект назвіть RandomNum.

Встановіть на форму Memo, видаліть з нього весь текст. Нижче кнопку з назвою «Генерувати».

рис. 9.2. Остаточний вигляд форми

У обробнику натискання на кнопку впишемо такий текст: procedureTfMain.Button1Click(Sender: TObject); const MaxValue = 1000; //записуємо максимальний розмір випадкових чисел var a : array [1..100] ofInteger; //масив цілих чисел з 100 елементів i : integer; //лічильник для for

s : String;

begin //спочатку очистимо Memo:

Memo1.Clear; //Заповнюємо випадковими числами від 0 до MaxValue масив a:

fori := 1 to 100 do

a[i] := Random(MaxValue); //дані з масиву додаємо спочатку в //строкову змінну, потім в Memo:

s :=’’;

for i := 1 to 100 do

s := s + IntToStr(a[i]) + ', ';

Memo1.Lines.Add(s);

end;

В результаті виконання цього коду ми отримаємо рядок s, в якій через кому будуть перераховані 100 випадкових чисел від 0 до 1000, яку потім додамо в компонент Memo.

Оператор циклу repeat...until

Ми вже знаємо умовний цикл while, вивчимо ще один. Синтаксис циклу нескладний:repeat<тіло циклу>until<умова>;

Якщо цикл while мав передумова, то цикл repeat має постумову, яке виконується після тіла циклу. Є ще відміна - цикл while виконується до тих пір, поки умова вірна, а цикл repeat буде виконуватися, поки умова помилкова. У циклі while, якщо умова спочатку помилкова, тіло циклу ніколи не буде виконуватися. Repeat виконає тіло циклу принаймні один раз. Потім оператор перевіряє умову, і якщо воно помилкова, виконує тіло циклу ще раз, і так до тих пір, поки <умова> не поверне істину. Ще одне зауваження: зарезервовані слова repeat...until працюють як дужки begin...end, тому в тілі циклу може бути скільки завгодно інструкцій, які вже не потрібно укладати в begin...end. Приклад:

i := 3;

repeat

i := i + 1;

ShowMessage('i = ' + IntToStr(i));

until i > 10;

Форма About засобами Delphi

Форму About зовсім не обов'язково розробляти самостійно, Delphi вже надає нам таку форму. Потрібно буде лише змінити текст, і при необхідності, картинку.

У попередньому проекті, де ми виводили випадкові числа, створіть головне меню. У цьому меню створіть пункти «Файл - Вихід» і «Довідка Про програму».

Виберіть команду «Файл " - New - Other». Відкриється вікно репозитарію, своєрідною колекції шаблонів і майстрів для створення потрібного вікна. Це вікно має багато вкладок, в яких вікна і шаблони розбиті за тематиками. Перейдемо на вкладку Forms і виберемо шаблон «About box». Відразу ж перейменуємо форму в fAbout, а властивості Caption нової форми присвоїмо текст «Про програму». Модуль форми збережемо під ім'ям About. Форма має цілком закінчений дизайн, залишилося лише вписати потрібний текст у компоненти Label і при необхідності змінити картинку.

Упершій label напишемо: «Product Name: RandomNums». Удругий: «Version: 1.0». Майте на увазі, що у світовому співтоваристві прийнято давати номери версій програм від 1.0 і вище. Якщо у наступній версії відбулися незначні зміни, назвіть версію 1.1, потім 1.2 і так далі. Іноді навіть вказують три цифри: 1.0.1, 1.0.2 і вище, вирішувати вам. Якщо значні зміни, практично у вас вийшла інша програма, тоді називайте версію 2.0.

У третій Label напишіть «Copyright: своє ПІБ». Цей розділ вказує, хто має авторське право на продукт. У четвертій Label знаходиться розділ Comments. Тут потрібно дуже коротко і по суті написати, що робить ваша програма, для чого вона призначена. Ви можете перевести всі на російську мову. Замість «Product Name» напишіть «Програма». «Version» замінити на «Версія». «Comments» замінити на «Коментарі». А ось слово «Copyright» переводити не потрібно, саме таким чином прийнято зазначати авторське право в світовому співтоваристві.

Якщо ви зробили форму до кінця, збережіть її і пропишіть у розділ uses головної форми. Далі в меню головною форми двічі клацніть по підрозділу «Про програму» і створіть там обробник виклику нової форми.

Лекція 10. Символьні типи даних

Символ

Символ - це один знак. Будь-який - буква, цифра, арифметичний знак або пробіл, знак пунктуації або підкреслення... А також спеціальні символи - перехід на новий рядок, BackSpace, знак долара або відсоток. Тип «символ» Delphi позначається Char:

var

c : Char;

begin

c := 'В';

ShowMessage('Вы ввели ' + c); c := #13;

ShowMessage('Переход на новую' + c + 'строку'); …

Ми вже говорили, що символи беруться з таблиці символів ANSI або UNICODE. Більшість символів використовуються користувачами, деякі символи є службовими. Зверніть увагу, що велика літера «А» і маленька «а» - це різні символи! Також різними символами є латинська «с» і кірилічна «с», хоча вони схожі.

Нульовий символ не використовується, він зарезервований як повний нуль. Програмісти знайшли гідне застосування цього символу, використовуючи його в подіях введення тексту, коли потрібно заборонити користувачу введення будь-яких символів. Службові символи ми не можемо побачити в текстовому полі. Службові символи, це <Esc>, <Enter>, <Tab> та інші. Кожен символ обробляється комп'ютером як число від 0 до 255, таким чином, слово «ПРИВІТ» в пам'яті машини буде виглядати як набір цифр: «207 208 200 194 197 210».

Функції роботи з символами

У практиці часто доводиться обробляти окремі символи. Змінним символьного типу Char можна привласнювати значення таким чином:

var c,b : Char;

begin c := 'a'; b := c;

Оскільки для комп'ютера символ - число, то символьні дані можна порівнювати між собою. При цьому більшим буде той символ, число якого в таблиці символів більше. Наприклад, ‘я’ буде більше, ніж ‘а’:

if b > c then ShowMessage('Істина!') else ShowMessage('Брехня!');

При роботі з символьними змінними часто використовують функції(Chr) і Ord(). Функція(Chr) приймає в якості параметра число, і повертає символ, який відповідає цьому числу в таблиці ANSI:

functionChr ( X: Byte ): Char;

Функція Ord() здійснює прямо протилежне дію, вона приймає в якості параметра символ, і повертає число, під яким цей символ зберігається в таблиці ANSI:

functionOrd ( C: Char ): Byte;

Символьні змінні можна використовувати з цими функціями:

a := Chr(200);

i := Ord(a);

i := Ord('f');

У першому рядку в змінну a ми записали літеру «І», якому в таблиці символів відповідає номер 200. У другу, цілу змінну, ми записали цифру 200, так як символ з цим номером був записаний в змінну a, яку ми передали в якості параметра. Нарешті, у третьому рядку ми цілу змінну записали цифру 102, цей номер відповідає символу «f».

Рядок

Рядок - це набір символів. Рядок можна представити у вигляді статичного та динамічного масиву символьних даних. Типи рядків ми вже розбирали в 4 лекції: AnsiString - рядок з ANSI - символів, і WideString - рядок з UNICODE - символів.

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

var s : String; begin

s := 'Цебагаторядкова' + #13 + 'рядок'; ShowMessage(s);

Як видно з прикладу, рядок можна складати з декількох підрядків, і навіть додавати до неї окремі символи, у тому числі і спеціальні. У прикладі ми додали символ під номером 13, це символ переходу на новий рядок. В результаті виконання цього коду процедура ShowMessage() виведе на екран повідомлення, розбите на два рядки:

Це багаторядковий рядок

ShortString - короткий рядок з ANSI - символів. Може містити від 0 до 255 символів. Використовується нечасто. Власне, ви можете оголосити тип String із заздалегідь вказаним розміром:

var s : String[100];

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

var stroka : String; begin

stroka := 'Привіт';

stroka[5] := 'а'; //змінили 5-й символ рядка

ShowMessage(stroka); //результат: рядок "Приват"

PChar

Це теж рядок, і в майбутньому нам доведеться з нею зустрічатися. Цей рядок працює зовсім інакше, ніж String. Рядок String являє собою масив символів, в нульовому елементі якого міститься кількість байт, що відводяться під цей рядок. А змінна типу PChar - це не сама рядок, а курсор на початок рядка, тобто мінлива вказує на перший символ рядка в пам'яті комп'ютера. А де ж тоді PChar зберігає кількість байт у рядку?! А ніде! Ми вже говорили про таблиці символів ANSI, і з'ясували, що нульовий символ - порожній. Ось останній символ PChar як раз і зберігає цей символ, і комп'ютер, знайшовши його, вважає, що рядок закінчена.

З рядками PChar працювати дуже незручно, проте нам доведеться це робити, коли ми будемо працювати з функціями WinAPI напряму. Функції WinAPI - це функції самої Windows, а не Delphi. Однак Delphi дозволяє використовувати їх. Іноді це буває необхідно, наприклад, коли коштів Delphi недостатньо для виконання поставленої задачі. Використання таких функцій не завжди зручно, проте вони виконуються процесором набагато швидше, так як містяться в самій операційній системі. Приклад - функція MessageBox().

Ви вже звикли виводити повідомлення за допомогою функції Delphi ShowMessage()? Звикайте до нової функції!

Application.MessageBox('рядок 1', 'рядок'[2, кнопки + тип_окна]);

Тут: рядок 1 - виводить текст всередині вікна. рядок 2 - текст заголовка вікна. Якщо не вказувати [кнопки + тип_окна] то вийде просте вікно з кнопкою ОК, як у функції ShowMessage().

Таблиця 10.1. Типи кнопок.

Кнопки

Опис

MB OK

(ОК)

MB OKCANCEL

(ОК и Відміна)

MB RETRYCANCEL

(Повторити и Відміна)

MB YESNO

(Так и Ні)

MB YESNOCANCEL

(Так, Ні и Відміна)

MB ABORTRETRYIGNORE

(Зупинити, Повтор Пропустити)

Таблиця 10.2. Типи вікон.

Тип вікна

Опис

MB ICONWARNING

(жовтий трикутник с "!")

MB ICONINFORMATION

(біла кулька с "i")

MB ICONQUESTION

(біла кулька с "?")

MB ICONERROR

(червоний круг с білим хрестиком)

Ця функція, крім виводу повідомлення, також повертає значення - ідентифікатор кнопки, яку користувач натиснув:

Таблиця 10.3. Яке повертає значення:

Значення

Натиснута кнопка

IDOK

ОК

IDCANCEL

Відміна

ID ABORT

Зупинити

IDRETRY

Повтор

IDIGNORE

Пропустити

IDYES

Так

IDNO

Ні

Приклад використання:

Application.MessageBox('Помилка копіювання файлу!', 'Помилка', MB_ABORTRETRYIGNORE+MB_ICONERROR)

У результаті виконання цієї функції програма виведе вікно:

Рис. 10.1. Вікно функції MessageBox()

Давайте відразу спробуємо цю функцію на прикладі. Створіть новий додаток. На форму встановіть компонент Label для виведення результату, і кнопку. У властивості Caption компонента Label видаліть весь текст. Створюємо обробник натискання кнопки. Оскільки функція MessageBox возвращает яка перераховується значення, ми можемо використовувати case. Пишемо такий код:

caseApplication.MessageBox('Помилка копіювання файлу!', 'Помилка', MB_ABORTRETRYIGNORE+MB_ICONERROR) of

IDABORT : Label1.Caption := 'Відмінити';

IDRETRY : Label1.Caption := 'Зациклити';

IDIGNORE: Label1.Caption := 'Ігнорувати'; end; //case

У прикладі як selector для case ми вказали саму функцію. Коли користувач натисне одну з кнопок, функція поверне числове значення, відповідне константі однієї з кнопок. В результаті, виконається потрібний код, і в властивість Caption компонента Label запишеться, яка з кнопок була натиснута.

Збережіть приклад, відкомпілюйте і подивіться, як він працює. Спробуйте змінити тип вікна на інший, наприклад на MB_ICONQUESTION. Функції роботи з рядками

Використовуючи операції порівняння=, <, >, <=, >= рядки можна порівнювати між собою. При цьому більшої вважається та рядок, в однаковій позиції якої знаходиться символ з великим кодом. Якщо всі символи однакові, рядки вважаються рівними. Приклади: Таблиця 10.4. Приклади порівняння рядків.

Рядок1

Рядок2

Результат порівняння

Іванов

Іванов

Рядки рівні

васильев

Васильев

Рядок 1 >Рядка 2

Олексеєв

Петров

Рядок 1 <Рядка 2

Іванова

Іванов

Рядок 1 >Рядка 2

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

Length()

Дуже корисна, і часто використовується функція. Вона повертає довжину рядка (кількість символів). Прикладивикористання:

Var s : String; i : Integer;

begin s := 'Іванов';

i := Length(s); //результат– 6

i := Length('Іванова'); // результат– 7

Процедура Delete

Процедура принимает в качестве параметра срока и удаляет какую-то ее часть. Синтаксис процедуры такой:

Delete(Строка, p, n);

где: Строка - переменная строкового типа.

p - номер символа, с которого начинается удаление.

n - количество удаляемых символов.

Пример использования:

s := 'Город Санкт-Петербург'; Delete(s, 7, 6);

результате выполнения данного кода в строке s останется текст «Город Петербург».

Функція Pos()

Функція знаходить підрядок Substr у рядку S і повертає індекс першого символу знайденої підрядка. Якщо S не містить зазначену підрядок, то функція повертає 0:

Функція Pos (Substr: string; S: string): Integer;

Приклад використання:

var S: string; I: Integer;

begin S:= 'У лісі народилася ялинка'; I:= Pos( 'ліс', S); // I = 3 end;

Функція Copy()

Функція повертає підрядок розміром Count символів, починаючи з символу Index. Параметр S - передана у функцію рядок; Index і Count - цілі числа. Якщо Index більше довжини рядка, то функція повертає порожній рядок. Якщо значення параметра Count більше, ніж може бути повернуто функцією, то повертаються символи або елементи, починаючи з Index і до кінця S.

function Copy(S, Index, Count): string;

Прикладвикористання:

var S: string; begin

S:= 'Перемога';

S:= Copy( S, 3, 4); // S = 'біда' end;

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

Лекція 11.

Структура проекту

Досі ми створювали програми, не замислюючись про те, які файли при цьому створюються, для чого вони потрібні. Нам зрозуміло, що файл проекту з розширенням *.exe - це сама програма, яка вийшла після компіляції проекту. Файли з розширенням *.pas - файли модулів, що містять вихідний код програми. Настав час докладніше вивчити структуру проекту, з яких файлів він складається, для чого вони потрібні, яка їх внутрішня структура.

Модуль

Проект в Delphi являє собою набір програмних одиниць - модулів. Модуль англійською мовою називається Unit. Коли ми розробляємо форму, ми одночасно обробляємо модуль цієї форми. Модуль - це файл з розширенням *.pas. Це розширення - скорочення від мови програмування Pascal, на якому будувалася Delphi. Інакше кажучи, модуль - вихідний код програми, або «джерело». Як тільки ми створюємо нову форму, відразу ж створюється і модуль для неї. Delphi заповнює цей модуль необхідним кодом, а нам залишається створювати код для обробки кнопок і різних подій.

Давайте на прикладі вже робочої програми подивимося, з чого складається проект. Відкрийте проект MyNotebook з лекції 8. Перейдіть на редактор коду.

На самому верху ви бачите рядок

unit Main;

Unit - це зарезервоване слово, що позначає Модуль форми. Зарезервованими називаються службові слова, які вже мають власні назви в компіляторі, і такі назви не можна давати змінним, констант, масивів, компонентів, функцій або процедур. Зарезервовані слова в коді завжди виділяються жирним шрифтом, ви можете бачити це на прикладі таких слів, як unit, interface, uses, begin або end, і так далі:

Рис. 11.1. Фрагмент редактора кода

Коли ми створювали форму, то відразу дали їй ім'я (властивість Name) fMain. А коли зберігали проект, Delphi насамперед запитала ім'я для модуля форми. Ми назвали модуль також як форму, але без початкової літери f - Main. Ось чому нагорі коду unit (Модуль) цієї форми має ім'я Main. Тепер ви розумієте, як важливо дотримуватися правила найменування форм і модулів? Коли в проекті буде багато форм, то і модулів буде багато, і якщо ви не будете дотримуватися цих правил, то запросто заплутаєтеся в назвах. І також важливо давати форм і модулів осмислені імена. У складних проектах таких форм і модулів може бути сотні!

Але повернемося до проекту MyNotebook. Подивіться на код. Далі йде службове слово interface. Ця директива повідомляє компілятору, що починається розділ інтерфейсу. В цьому розділі, насамперед, зазначаються модулі, підключені до даного модуля. Вони описуються після службового слова uses. Коли ми вводимо котрусь функцію або процедуру, ми не замислюємося, звідки вона береться. А ця функція описана в одному з підключених модулів! Давайте в цьому переконаємося. Спустіть курсор в нижню частину модуля. Останній у нас описана процедура виклику модального вікна fAbout. Нижче цього дзвінка введіть рядок: ShowMessage('Привіт!');

Вона тут зовсім не потрібна, і потім ми її видалимо. А поки що встановіть курсор всередині самого слова ShowMessage, і натисніть <Ctrl>+<> F1. Тим самим, ви викликаєте контекстну довідку саме про цю команду. І в самому початку довідки ви бачите вказівку, в якому модулі описана процедура:

Unit Dialogs or QDialogs

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

До речі, кількість підключених до формі модулів пояснює, чому, здавалося б, невеликий проект має досить великий розмір *.exe файлу. Адже підключені модулі містять безліч описів функцій і процедур, і навіть якщо ми не використовуємо їх, вони все одно доступні. Однак турбуватися з цього приводу не варто - нам навряд чи доведеться писати програми, для яких важливий розмір виконуваного файлу. Це, як правило, драйвери або віруси, і хоча на Delphi можна написати і те, і інше, для цих завдань більше підходить чистий C або навіть Assembler. А якщо ви будете використовувати Borland C++ Builder або Microsoft Visual C++, то і вони мають безліч підключених модулів, і розмір навіть маленької програмки також виявиться більшим.

Коли ми створювали форму, то відразу дали їй ім'я (властивість Name) fMain. А коли зберігали проект, Delphi насамперед запитала ім'я для модуля форми. Ми назвали модуль також як форму, але без початкової літери f - Main. Ось чому нагорі коду unit (Модуль) цієї форми має ім'я Main. Тепер ви розумієте, як важливо дотримуватися правила найменування форм і модулів? Коли в проектібуде багато форм, то і модулів буде багато, і якщо ви не будете дотримуватися цих правил, то запросто заплутаєтеся в назвах. І також важливо давати форм і модулів осмислені імена. У складних проектах таких форм і модулів може бути сотні!

Але повернемося до проекту MyNotebook. Подивіться на код. Далі йде службове слово interface. Ця директива повідомляє компілятору, що починається розділ інтерфейсу. В цьому розділі, насамперед, зазначаються модулі, підключені до даного модуля. Вони описуються після службового слова uses. Коли ми вводимо котрусь функцію або процедуру, ми не замислюємося, звідки вона береться. А ця функція описана в одному з підключених модулів! Давайте в цьому переконаємося. Спустіть курсор в нижню частину модуля. Останній у нас описана процедура виклику модального вікна fAbout. Нижче цього дзвінка введіть рядок:

ShowMessage('Привіт!');

Вона тут зовсім не потрібна, і потім ми її видалимо. А поки що встановіть курсор всередині самого слова ShowMessage, і натисніть <Ctrl>+<> F1. Тим самим, ви викликаєте контекстну довідку саме про цю команду. І в самому початку довідки ви бачите вказівку, в якому модулі описана процедура:

Unit Dialogs or QDialogs

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

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

private { Private declarations }

public { Public declarations }

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

Далі йде опис глобальних записів, констант і змінних. Тут у нас є тільки одна глобальна змінна:

var fMain: TfMain;

Це - форма. Так, так, не дивуйтеся, форма - це мінлива типу TForm. Точніше, не просто невелика, а об'єкт зі своїми властивостями, подіями і методами.

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

У цьому розділі глобальних змінних ми можемо створити власну змінну:

Var

fMain: TfMain;

adres: String; //для адреси, звідки запущена програма

Потім виділити головну форму, перейти на вкладку Events (Події) і подвійним клацанням миші згенерувати подія OnCreate, що відбувається один раз, при створенні форми, або ж OnActivate , яке відбувається, коли форма стає активною. У цій події прописати такий рядок:

adres := ExtractFilePath(Application.ExeName);

Змінну adres в отриманої процедурі описувати не потрібно - вона глобальна, та ми її вже описали. Функція Application.ExeName поверне повне ім'я файлу нашої програми, а функція ExtractFilePath() вычленит з цього імені адресу, і поверне його. Надалі, в будь-якій процедурі або функції модуля, де буде необхідно звернутися до файлу, наприклад, myparam.ini, який знаходиться там же, звідки запущена програма, достатньо вказати:

... adres + 'myparam.ini' ...

і ми отримаємо ім'я файлу разом з повною адресою, звідки б програма не була запущена.бути програми, для яких важливий розмір виконуваного файлу. Це, як правило, драйвери або віруси, і хоча на Delphi можна написати і те, і інше, для цих завдань більше підходить чистий З або навіть Assembler. А якщо ви будете використовувати Borland C++ Builder або Microsoft Visual C++, то і вони мають безліч підключених модулів, і розмір навіть маленької програмки також виявиться більшим.

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

Private

{ Private declarations }

Public

{ Public declarations }

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

Далі йде опис глобальних записів, констант і змінних. Тут у нас є тільки одна глобальна змінна:

var fMain: TfMain;

Це - форма. Так, так, не дивуйтеся, форма - це мінлива типу TForm. Точніше, не просто невелика, а об'єкт зі своїми властивостями, подіями і методами.

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

У цьому розділі глобальних змінних ми можемо створити власну змінну:

var fMain: TfMain;

adres: String; //для адреси, звідки запущена програма

Потім виділити головну форму, перейти на вкладку Events (Події) і подвійним клацанням миші згенерувати подія OnCreate, що відбувається один раз, при створенні форми, або ж OnActivate , яке відбувається, коли форма стає активною. У цій події прописати такий рядок:

adres := ExtractFilePath(Application.ExeName);

Змінну adres в отриманої процедурі описувати не потрібно - вона глобальна, та ми її вже описали. Функція Application.ExeName поверне повне ім'я файлу нашої програми, а функція ExtractFilePath() вычленит з цього імені адресу, і поверне його. Надалі, в будь-якій процедурі або функції модуля, де буде необхідно звернутися до файлу, наприклад, myparam.ini, який знаходиться там же, звідки запущена програма, достатньо вказати:

... adres + 'myparam.ini' ...

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

Далі йде розділ implementation. Це розділ реалізації. Він містить самі процедури і функції, які підтримують роботу цієї форми. Крім того, в цьому розділі також може бути директива uses, в якій оголошені модулі, підключені до даної форми. Дана директива необязателена - якщо у вашому проекті тільки одна форма, то її не буде зовсім. Якщо є ще одна форма, як у нашому прикладі - форма fAbout, модуль якої називається About, то цей розділ додається автоматично, як тільки ви скористаєтеся командою File -> Use Unit. Відразу під ключовим словом implementation у нас є рядок

uses About;

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

Далі ви бачите таку рядок, виділену зеленим кольором:

{$R *.dfm}

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

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

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

Закрийте цей проект, зберігати його не потрібно, команда ShowMessage, яку ми дали для прикладу, в програмі не потрібна. Створіть новий проект і перейдіть в редактор коду. Відразу після директиви компілятора ви бачите рядок активним. У цій події прописати такий рядок:

end.

Зверніть увагу, що слова begin перед ним немає і бути не повинно! Це - єдиний виняток з правила дужок begin..end. Власне, це навіть не виключення, тому що ця end не є закриває дужкою, це завершення модуля.

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

Файли проекту

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

Таблиця 11.1. Опис файлів проекту

Розши- рення

Опис файлу

*.cfg

Цей файл містить конфігурацію всього проекту, тому він один, і має ім'я, як у проекту. Редагувати цей файл вручну не варто, якщо не хочете зіпсувати проект.

*.dof

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

*.dpr

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

*.res

Файл ресурсів проекту, таких як іконки, курсори і так далі..

*.pas

Модуль форми. Цей файл ми бачимо в редакторі коду, його ми редагуємо. Таких файлів є по одному на кожну форму проекту.

*.dfm

Це файли з інформацією про формі. Тут містяться описания використовуваних компонентів та їх налаштування.

*.ddp

Це допоміжні файли модуля, вони генеруються автоматично.

*.dcu

Відкомпільований файл модуля. Фактично, та ж програма, але тільки для одного модуля. Працювати самостійно вона не може.

*.exe

Готова програма. Компілятор збирає всі *.dcu в єдиний виконуваний файл. Якщо ви в проекті не використали інших файлів, таких як бази даних, наприклад, то цей файл єдиний, який потрібен. При розповсюдженні програми віддавайте користувачеві тільки його. Однак це не означає, що всі інші файли можна видалити. Адже в них ваш проект! У майбутньому, можливо, вам понадобитсяпроцедура або функція, аналогічна тій, яку ви використовували в проекті. Щоб заново не винаходити велосипед, просто відкрийте старий проект і подивіться, як ви реалізували цю функцію. Скопіюйте та вставте новий проект, якщо потрібно.

Файли, розширення яких починається з тильди - це резервні копії модулів і

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

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

*~*

Це попереднє збереження. Якщо ви зберегли проект, і побачили, що помилилися - його

можна відновити з цього файлу. Однак найкраще робити архівні копії

проекту перед кожним серйозною зміною програми.


Опис містить основні файли проекту. Іноді доводиться використовувати у проекті та інші файли, і ми будемо їх вивчати, коли прийде час застосовувати їх на практиці.

Лекція 12. Тип TStrings

Рядок і рядки TStrings

У практиці програмування найчастіше доводиться працювати з рядками. Будь то звичайний Edit або Memo, там використовуються рядка. І навіть якщо ви вставляєте Edit, щоб запитати у користувача число, він все одно вводить його в якості рядка, і вам потрібно перетворити його в числовий тип, щоб працювати з ним, як з числом.

Отже, що таке рядок? Фактично, це масив символів. Давайте подивимося приклад:

Var

s : String;

a : array [1..7] ofChar;

begin

s := 'Привіт!';

ShowMessage(s); //Результат: висновок рядка "Привіт!"

a[1] := 'П'; a[2] := 'р'; a[3] := 'і'; a[4] := 'в'; a[5] := 'е'; a[6] := 'т'; a[7] := '!'; ShowMessage(a); //Результат: висновок рядка "Привіт!"

ShowMessage(s[1]); //Результат: висновок букви "П" ShowMessage(a[1]); //Результат: висновок букви "П"

На жаль, ми не можемо просто так взяти і присвоїти масиву рядок - це буде помилкою, тому a := s не скомпілюється. Проте після того, як в масив ми символи ввели текст, це виходить вже повноцінної рядком, тому компілятор дозволить директиву ShowMessage(a);і програма попрацює без помилок. Зрозуміло, нерозумно використовувати масив символів там, де простіше використовувати змінну типу String. Цей приклад просто показує, що рядок - це той же масив символьного типу!

Однак ми з вами вже стикалися і з типом TStrings - рядка. Такий тип ми використовували у властивості Lines компонента Memo і ви вже переконалися, наскільки це потужний тип і як легко з ним працювати. Він дозволяє додавати або видаляти рядок зі списку рядків, з його допомогою легко записати рядки в файл або навпаки, завантажити їх з файлу. Тип TStrings присутній у багатьох компонентах, і скрізь ви з ним можна виконувати такі дії! Раз вже ми заговорили про масивах, то проведемо порівняння і для TStrings - це той же масив, тільки не типу Char (символ), а типу String (рядок):

a : array [1..10] of String;

Однак, хоча TStrings по своєму образу схожий на такий масив, він має безліч додаткових можливостей, тому використовуйте його скрізь, де постає мова про роботу з набором рядків!

Lіstbox - список вибору

Списки вибору зберігають в собі якісь списки, і дають користувачеві можливість вибирати одну із зазначених рядків. Часто їх застосовують у вікнах з заданими параметрами, щоб користувач міг вибрати один з параметрів.

Щоб отримати доступ до рядків списку, потрібно скористатися властивістю Items компонента Lіstbox. Ця властивість має тип TStrings (рядки), з таким типом ми стикалися, коли обробляли компонент Memo. Подивимося на практиці, як працювати з даним компонентом. Створіть новий додаток, встановіть на нього один компонент Lіstbox, і під ним - один Edit для виведення тієї рядка, яку вибрав користувач:

Рис. 12.1. Зовнішній вигляд форми.

Потім двічі клацніть по властивості Items компонента Lіstbox. Перед вами відкриється вже знайомий редактор рядків. Наберіть назви операційних систем: MS-DOS

Windows 3.10

Windows 95

Windows 98

WindowsME

Windows 2000

Windows XP

Windows Vista

Unix Linux

OS/2

Кожна назва операційної системи має бути на окремому рядку. Натисніть «ОК», щоб зберегти результат. Тепер створіть для компонента Lіstbox обробник подій onClick. Ми вже знаємо, що це подія спрацьовує всякий раз, коли користувач вибере один з рядків у вказаному списку. У обробнику подій напишіть тільки один рядок:

Edit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];

Цей рядок присвоює властивості Text компонента Edit той текст, який зберігається в обраній рядку списку Lіstbox. Властивість Items має свою властивість Strings, яке являє собою масив рядків списку. Вказавши індекс масиву, ми можемо отримати доступ до потрібної рядку. У прикладі як індексу зазначено властивість ListBox1.ItemIndex, яке має тип Integer і повертає елемент вибраної рядки в масиві рядків. До речі, коли ви поставите точку і відкриється список, там ви цього властивості не виявите, так що доведеться писати його вручну.

Збережіть приклад в нову папку, відкомпілюйте і подивіться, як він працює.

Крім того, ми маємо можливість програмно додавати в Lіstbox новий рядок або видалити вибрану. Киньте на форму ще дві кнопки і напишіть на них - «Додати рядок», «Видалити рядок». Додавати будемо рядок, написану в компоненті Edit, а видаляти - виділену.Для кнопки «Додати» впишіть: ListBox1.Items.Add(Edit1.Text);

а для кнопки «Видалити»:

ListBox1.Items.Delete(ListBox1.ItemIndex);

Збережіть, відкомпілюйте і подивіться, як він працює.

Часто буває необхідним надати користувачеві можливість множинного вибору. Користувач, утримуючи клавішу <Ctrl>, хапає за рядками і вибирає потрібні. Для цього у Lіstbox є властивість MultiSelect (множинний вибір). За замовчуванням воно одно False, тобто забороняє користувачу вибрати кілька рядків. Створимо ще один додаток, в якому продемонструємо можливість множинного вибору.

Встановіть на форму один Lіstbox і один Memo, нижче - кнопку з написом «Копіювати». При натисканні на кнопку будемо шукати у Lіstbox виділені рядки і копіювати їх у Memo. На малюнку 12.2 в лівій частині встановлений компонент Lіstbox, а в правій - Memo.

Рис. 12.2. Зовнішній вигляд програми

Увійдіть в редактор рядків Lіstbox і напишіть там

Рядок № 1 Рядок № 2

і так далі, поки не заповніть Lіstbox так, щоб його не потрібно було прокручувати. Встановіть властивість MultiSelect у Lіstbox в True. Не забудьте очистити Memo. Тепердлякнопкинапишемонаступнийкод:

procedureTForm1.Button1Click(Sender: TObject); var

i : Integer;

begin Memo1.Clear; for i := 0 to ListBox1.Count - 1 do if ListBox1.Selected[i] then

Memo1.Lines.Add(ListBox1.Items.Strings[i]); end;

Спочатку ми очистили Memo, щоб користувач міг кілька разів випробувати вибір та копіювання рядків, і рядки в Memo не скупчувалися.

Потім ми створюємо цикл, щоб обробляти Lіstbox рядках. Перший рядок завжди має нульовий індекс, а властивість Count у всіх об'єктах TStrings повертає кількість рядків в об'єкті. Нам доводиться відняти одиницю, так як індекси починаються не з 1, а з 0. Далі в цикл ми помістилиумовний оператор if - якщо умова вірно (тобто рядок виділена), то робимо додавання рядка в Memo. За це відповідає властивість Selected (Виділено) з вказівкою індексу рядка. Якщо воно одно True, то рядок виділена. ComboBox - розкривний список.

Такі списки ви часто зустрічається при роботі з Windows і різними програмами. Діють і працюють вони також як Lіstbox, з тією лише різницею, що виглядають по-іншому, і не дозволяють вибрати кілька елементів відразу. Створіть новий додаток, додайте туди тільки один ComboBox і один Edit:

Рис. 12.3. Зовнішній вигляд програми

Викличте редактор рядків ComboBox (властивість Items) Впишіть кілька міст:

Москва

Санкт-Петербург

Київ

Мінськ

Ташкент

Душанбе

Властивість ItemIndex, яке, як ми знаємо, вказує індекс виділеної рядка, за умовчанням встановлено в-1. Це означає, що жодна не вибрано рядок. Якщо встановити його в 0, то в поле введення тексту з'явитися перший рядок списку. Залишимо -1, щоб рядків не було видно.

Створимо обробник подій OnChange для компонента ComboBox, і там напишемо тільки один рядок: Edit1.Text := ComboBox1.Items.Strings[ComboBox1.ItemIndex];

Як бачите, це майже точна копія роботи з Lіstbox. Збережіть приклад в нову папку, відкомпілюйте і спробуйте як він працює.

Управління циклами

Ви знаєте вже практично всі цикли - for..do, while..do, repeat..until. Проте цими циклами можна ще й керувати. Для цього служать директиви break і continue.

Break - переривання циклу. Якщо всередині циклу зустрінеться такий оператор, відбувається негайний вихід з циклу. Як правило, цей оператор використовують спільно з керуючою структурою if, наприклад: if a >< b then break;

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

Continue - переривання поточного кроку циклу. На відміну від break, continue не припиняє цикл зовсім, а лише перериває подальшу обробку цього кроку циклу, після чого цикл відразу починається з наступного кроку. Спосіб застосування такої ж, як у break. Розглянемо роботу continue на практичному прикладі.

Нам потрібно розділити число на 10 числа від -3 до 3 включно, та вивести результат у ListBox. Оскільки виводити будемо також цілі числа, нам допоможе функція Round(), яка приймає дійсне число, округлює його до найближчого цілого і це ціле возвращает. Також ми знаємо, що на нуль ділити не можна, це помилка. Для того, щоб не допустити це поділ, ми перервемо цей крок циклу з допомогою директиви continue.

Створіть новий додаток. Встановіть на форму Lіstbox, а під ним - кнопку:

Рис. 12.4. Зовнішній вигляд програми

При натисканні на кнопку, напишіть наступний код:

procedureTForm1.Button1Click(Sender: TObject); var

i, r : Integer;

begin fori := -3 to 3 dobeginifi = 0 thenbegin

ListBox1.Items.Add('нуль ділити не можна!'); Continue; end; //ifr :Round = (10/i);

ListBox1.Items.Add('10/'+IntToStr(i)+'='+IntToStr(r)); end; //forend;

В той момент, коли лічильник i стане рівним 0, виконається тіло умови if, і після оператора Continue цикл відразу перейде на новий виток, пропустивши поділ.

Самостійне завдання

У прикладі ми жорстко поставили умови: ділити саме число 10 на діапазон чисел від -3 до + 3. Змініть приклад так, щоб користувач міг сам вказати, яке число потрібно ділити, і на який діапазон. Це нескладне завдання, проте, доведеться підключити до роботи мізки.

Лекція 13. Діалоги

Діалоги

Що таке діалоги в Delphi? Це невизуальные, тобто, невидимі користувачеві компоненти, які виконують стандартні для Windows діалоги користувача і програми. Наприклад, діалог відкриття або збереження файлу, діалог вибору шрифту або кольору, і т.п. Будь-яка серйозна програма містить такі діалоги. Робота з ними нескладна, кожен діалог містить буквально за два властивості, які нам будуть потрібні. Вивчимо роботу діалогів на прикладі.

Відкриваємо новий проект. Відразу ж форму перейменовуємо в fMain, у властивості Caption пишемо «Мій блокнот». Збережіть проект під назвою Editor. Це буде більш професійна версія редактора текстів, який ми вже робили. Вважайте, що це друга версія програми, що і напишете у вікні fAbout.

Встановіть на форму компонент Memo, видаліть весь текст з його властивості Lines. Поверх Memo встановіть MainMenu і PopupMenu. Перейдіть на вкладку Dialogs на панелі компонентів, а також поверх Memo встановіть OpenDialog, SaveDialog, FontDialog і ColorDialog. Всі ці компоненти не візуальні, користувач їх бачити не зможе. У Memo відразу ж вкажіть властивість Align=alClient, а властивість ScrollBar=ssVertical. Рекомендую для кращого вигляду вибрати шрифт (властивість Font) Times New Roman, розмір = 12. На всіх комп'ютерах з російської Windows є цей шрифт, однак якщо ви будете писати програму для продажу в Інтернет, краще залишити шрифт за замовчуванням, це гарантує, що він буде читатися на всіх комп'ютерах в світі.

У всіх діалогах є один метод, який нас цікавить - Execution. Це метод логічного типу, він повертає True, якщо діалог з користувачем стався успішно (наприклад, користувач вибрав відкривається файл), і False в іншому випадку (наприклад, користувач відмовився від вибору файлу). У зв'язку з цим, діалоги зазвичай застосовують разом з перевіркою:

ifOpenDialog1.Executethen ...

У діалогах, пов'язаних з файлами (OpenDialog - відкрити файл, і SaveDialog - зберегти файл), є властивість FileName, яке повертає рядок - адресу та назву виділеного файлу. Ось, власне, і все, що нам потрібно від цих діалогів!

Діалог FontDialog у властивості Font возвращает вибраний шрифт. Це властивість непростий, воно має тип TFont, і привласнити його можна тільки іншому шрифту, наприклад:

Memo1.Font := FontDialog1.Font;

Точно також, діалог ColorDialog возвращает властивість Color - колір, що має тип TColor, і це властивість можна присвоїти тільки об'єкту, що має такий же тип:

Memo1.Color := ColorDialog1.Color;

Продовжимо наш проект. Відкрийте редактор головного меню. Створіть розділ «Файл» і підрозділи «Відкрити», «Зберегти», «Закрити», «-» і «Вихід». Створіть розділ «Настройки» і підрозділи «Вибрати шрифт» і «Вибрати колір». Створіть розділ «Довідка» і підрозділ «Про програму».

Тепер відкриваємо редактор PopupMenu і вписуємо розділи «Відкрити», «Зберегти», «Закрити», «-» і «Вихід». Відразу ж на формі виділяємо саму форму (це можна зробити у вікні Object - TreeView), і у властивості PopupMenu вибираємо наше меню. Тепер це меню відкриється, якщо користувач клацне правою кнопкою з будь-якого місця на формі.

Тепер нам потрібно налаштувати фільтри в діалогах OpenDialog (Відкрити) і SaveDialog (Зберегти). Фільтри дозволяють відображати в цих діалогах тільки потрібні формати файлів, і для цього вибору використовується маска. Приміром, маска *.* буде відображати файли всіх типів! Двічі клацнувши по властивості Filter діалогу OpenDialog, відкрийте редактор фільтрів. У першій колонці напишіть

«Текстові документи», другий - «*.txt». У рядку введіть «Всі файли», а у другій колонці - «*.*». Теж саме зробіть для діалогу SaveDialog:

Рис. 13.1. Настройка фільтра файлових діалогів

Тепер, відкриваючи файл, ви побачите тільки ці два типи файлів. Подумаємо про те, що програма повинна знати - чи змінився текст у Memo. Адже користувач може закрити програму і не зберегти текст, а потім буде лаяти програміста за те, що він цього не передбачив. При цьому маємо на увазі, що у нас є багато команд меню, значить, буде багато процедур. А щоб дати програмі знати, чи змінився текст, найрозумніше створити змінну логічного типу - змінився текст, присвоюємо їй True, інакше False. Щоб з цієї змінної можна було працювати з усіх процедур, вона повинна бути глобальною. Робимо глобальну змінну перед словом implementation:

izmen : Boolean; //чи змінився текст у Memo

Події onChange компонента Memo присвойте рядок:

izmen := True;

Як тільки зміниться текст у Memo, мінлива тут же буде видавати істину.

Тепер ще один момент - програма повинна знати ім'я та адресу відкритого файлу. Якщо імені файлу немає, то програма буде виводити діалогове вікно, а якщо ми файл вже відкривали і ім'я є, то програма просто буде перезаписувати той файл без виведення діалогового вікна. Стало бути, робимо ще одну глобальну змінну: myfile : String; //Адресу та ім'я відкритого файлу

Я спеціально не беру широко поширені слова «File» або «FileName», так як вони можуть бути зарезервованими або в компонентах можуть бути властивості з такими іменами, в результаті вийде конфлікт назв.

Метикуємо далі. Відкрити файл можна буде командою меню «Файл - Відкрити», або командою PopupMenu «Відкрити». Стало бути, нам доведеться двічі писати один і той же код? А якщо він буде великим і складним? Можна, звичайно, і скопіювати його, компілятор це витримає, і програма буде працювати нормально. А як же оптимізація коду? Два однакових коду в програмі будуть займати в два рази більше місця в пам'яті і на диску! Для цього ми маємо користувальницькі функції і процедури.

Згадуємо - функцію або процедуру ми повинні описати ВИЩЕ того місця, де будемо її використовувати, значить, першу нашу процедуру ми повинні описати в розділі implementation, прямо під рядком {$R *.dfm}.

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

Memo1. то компілятор відразу видасть помилку. Звертатися до компоненту потрібно, вказавши спочатку ім'я форми, на якій він знаходиться:

fMain.Memo1.

Однак такий код буде не дуже зручний - кожен раз доведеться звертатися до компонентів через форму. Зайвий набір коду, надто довгий текст. Вихід є - функція with (с). Ця функція має вигляд:

with fMain do begin

... end;

де fMain - ім'я форми з потрібними нам компонентами. Тепер між дужок begin...end цієї конструкції ми можемо звертатися до компонентів форми напряму. Пишемо загальну для всіх процедуру відкриття файлу:

{Процедура відкриття файла} procedureOtkrivaem; begin

withfMaindobegin //робити разом з формою

ifOpenDialog1.Executethenbegin //якщо діалог виконаний

//присвоюємо змінної myfile адресу та назву виділеного файлу: myfile := OpenDialog1.FileName;

//читаємо цей файл у Memo: Memo1.Lines.LoadFromFile(myfile);

izmen := False; //файл тільки відкритий, змін ще немає end; //endif; //withend;

Тепер створюємо обробник подій для команди меню «Файл - Відкрити». Там викликаємо нашу процедуру:

Otkrivaem;

Теж саме робимо для команди PopupMenu «Відкрити».

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

1. Користувач може зберігати новий файл, який він тільки що набрав. Тобто, мінлива myfile порожня і не містить ім'я файлу. У такому випадку доведеться виводити діалогове SaveDialog1, щоб користувач вказав ім'я файлу. Коли він вкаже ім'я, привласнити його змінної myfile і зберегти Memo у вказаний файл.

2. Користувач може зберігати новий файл, як у попередньому прикладі. Ми виведемо діалог, але він його не завершить - натисне кнопку «скасувати» або червоний хрестик у верхній частині вікна праворуч. Значить, зберігати нічого не потрібно, адже ми не знаємо, куди зберігати! Але доведеться його попередити, що файл не збережений!

3. Користувач може відкрити файл і змінити його, а потім зберігати. У змінній myfile це ім'я вже є, діалог не потрібна, просто перезаписуємо цей файл. 4. Користувач може зберігати файл, текст якого не змінювався. У такому випадку, просто ігноруємо його команду!

Бачите? Користуватися діалогами нескладно, але як багато доводиться враховувати під час перевірок дій користувача! Потрібно враховувати кожну дрібницю, інакше вам скажуть, що ваша програма повна «багів» - дрібних несправностей. Отже, пишемо процедуру збереження, відразу під процедурою відкриття:

{Процедура збереження файлу}

procedure Sohranyaem;

begin

with fMain do begin

//якщо змін не було, виходимо з процедури,

//нічого не роблячи:

if not izmen then Exit;

//Якщо файл вже відкривався, і в змінній myfile

//є його адреса та ім'я, просто перезаписуємо цей файл:

if myfile<> ’’ then

begin

Memo1.Lines.SaveToFile(myfile); izmen := False;

Exit; //виходимо після збереження

end;

{Файл новий, змінна myfile ще порожня. Далі є два варіанти: користувач вибере або вкаже файл у діалозі, або не зробить цього} //якщо вибрав файл:

Іf SaveDialog1.Execute then begin

//прописуємо адресу та ім'я файлу змінну:

myfile := SaveDialog1.FileName;

//якщо немає розширення *.txt то додаємо його:

if copy(myfile, length(myfile)-4, 4) <> '.txt' then

myfile := myfile + '.txt';

//зберігаємо Memo у вказаний файл:

Memo1.Lines.SaveToFile(myfile); //файл збережено, змін немає:

izmen := False; end

if //

//якщо не вибрав файл:

else ShowMessage('Ви не вказали ім'я файлу, файл не збережений!');

end; //with end;

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

Тепер ми можемо створити обробник головного меню «Файл - Зберегти», і там прописати виклик цієї процедури:

Sohranyaem;

Теж саме робимо для команди PopupMenu «Зберегти».

Далі йде команда головного і спливаючого меню «Вихід». Тут все просто, в обох випадках пишемо команду

Close;

Далі йде розділ «Настройки». Створюємо обробник «Вибрати шрифт», там все просто:

ifFontDialog1.Executethen

Memo1.Font := FontDialog1.Font;

Точно також і з підрозділом «Вибрати колір»:

ifColorDialog1.Executethen

Memo1.Color := ColorDialog1.Color;

Далі повернемося в розділ «Файл». Тут у нас залишився підрозділ «Закрити». Створюємо для нього обробник, в який запишемо:

{якщо файл не збережений, попереджаємо користувача про це. Якщо він бажає зберегти, то викликаємо процедуру збереження:} if izmen then

if Application.MessageBox('Файлзмінено. Зберегти?', 'Увага!', MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;

//тепер закриваємо поточний файл: Memo1.Clear; //очищаємо Мемо myfile := "; //немає імені поточного файлу izmen := False; //немає змін

Тут не так багато тексту, і він цілком зрозумілий, тому не будемо для нього робити окрему процедуру. Просто скопіюйте текст, створіть обробник подій для «Закрити» PopupMenu та вставте цей же текст туди.

Приблизно теж саме нам доведеться зробити і для події форми onClose - адже ми заздалегідь не можемо знати, яким чином користувач закриє форму, через пункт головного меню «Файл - Закрити», через команду контекстного меню «Закрити», натисне чи він червоний хрестик нагорі або натисне гарячі клавіші <Alt + F4>! Тому для перевірки - чи є в програмі незбережений текст, ми використовуємо подія onClose, що трапляється при спробі закрити форму, тобто в даному випадку всю програму. Тут код буде таким же, як і в попередньому прикладі, але раз ми закриваємо всю програму, нам не потрібно виконувати блок закриття файлу. Просто перевіримо, чи є зміни, і якщо вони є, виведемо запит - чи зберегти їх. Якщо користувач скажуть «Так», значить, викличемо процедуру збереження:{якщо файл не збережений, попереджаємо користувача про це. Якщо він

бажає зберегти, то викликаємо процедуру збереження:} ifizmenthen

ifApplication.MessageBox('Файл змінено. Зберегти?', 'Увага!', MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;

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

Відкрийте редактор MainMenu, в розділі «Файл» в самому низу додайте підрозділ «Очистити». Потім перетягніть мишкою його на місце лінії розділів, при цьому лінія опуститься вниз, а новий підрозділ встане на її місце:

Рис. 13.2. Вигляд головного меню

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

{MainMenu - Файл - Очистити}

procedureTfMain.N17Click(Sender: TObject);

begin //очищаємо Мемо: Memo1.Clear;

//якщо відкритого файлу немає, то немає і змін: ifmyfile = " thenizmen := false //інакше текст змінено: elseizmen := true; end;

Зробіть те ж саме для спливаючого меню - створіть розділ «Очистити», а в його обробник скопіюйте той же текст.

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

Все, зберігайте, компилируйте і перевіряйте, як працює програма! У нас вийшов нескладний, але цілком професійний редактор текстів. Одне зауваження: текст ми зберігаємо, але вибраний шрифт і колір вікна ви не можете зберегти, про це ми будемо говорити на інших лекціях, коли навчимося зберігати параметри.

Лекція 14. Адреса та ім'я файлу

Тип Variant

Бувають випадки, коли на етапі програмування ми ще не можемо чітко визначити тип даних певної змінної. У такому випадку можна скористатися дуже потужним типом Variant. Цей тип вводився в Delphi для підтримки технології OLE (ObjectLinkandEmbedding - впровадження і зв'язок об'єктів). Така технологія широко використовується в Windows для обміну даними між додатків різного типу. За допомогою OLE відбувається вставка таблиці MS Excel в текстовий редактор MS Word, або картинка з Paint легко вставляється в той же редактор. У цій технології Variant використовується на кожному кроці, проте йому можна знайти застосування і в інших випадках.

Змінні типу Variant можуть приймати значення будь-якого типу! Ви присвоює такий змінної що завгодно, а програма сама визначає її тип на етапі виконання. Давайте розглянемо приклад:

var V : Variant;

begin V := 5; //привласнили ціле число

V := 'текст'; //привласнили рядок

V := True; //тип логічний

V := 3,14; //речовинний тип end;

У цьому прикладі під час виконання програми тип змінної зміниться 4 рази, і код виконається коректно. Коли програма зустрічає тип Variant, вона автоматично виділяє під неї пам'ять. Якщо значення не вказано, змінної присвоюється нуль.

Порада: намагайтеся використовувати тип Variant тільки там, де це дійсно необхідно! За зручність використання такої змінної теж доводиться платити. Мінлива такого типу займає значно більше пам'яті, ніж мінлива будь-якого іншого типу. Процесору ми теж ставимо зайву роботу, адже спочатку потрібно визначити тип даних у змінній, потім присвоїти цей тип самої змінної, і т.п. Крім того, змінні типу Variant дуже складно налагоджувати у великих програмах. Складаючи, наприклад, рядок і ціле число, ви можете отримати зовсім не той результат, який очікували!

Розглянемо приклад:

var v1, v2, v3 : Variant;

begin v1 := '1'; v2 := '5'; v3 := 10;

v1 := v1 + v2 + v3; end;

Як ви вважаєте, який результат виявиться врешті-решт у змінній v1? На перший погляд, результат очевидний: число 16. Однак не поспішайте з висновками. Коли оператори обчислення мають рівний пріоритет, вони виконуються зліва направо. У даному прикладі спочатку об'єднаються символи, в результаті чого вийде рядок «15». Потім ця рядок перетворюється в ціле число, і до нього буде додано число 10. Тому результат складання - 25.

Функції для роботи з ім'ям файлу

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

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

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

Функція ExtractFileName()

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

var S: string; begin

... S := ExtractFileName( 'C:\DIR1\myfile.txt'); // S = 'myfile.txt' ... end;

Функція ExtractFilePath()

Функціяповертаєшляхдофайлу, дістаючийогозповногоіменіфайлу. Якщо ім'я файлу не містить ні ім'я каталогів, ні ім'я диску, то функція повертає порожній рядок. Подібне ж дію виконує функцію ExtractFileDir(). Відмінність цих функцій в тому, що в кінці цієї адреси функції ExtractFilePath() є знак «\», а функція ExtractFileDir() цей знак не встановлює:

var S: string; begin

... S:= ExtractFilePath( 'C:\DIR1\DIR2\myfile.zzz'); //S ='C:\DIR1\DIR2\' S:= ExtractFileDir( 'C:\DIR1\DIR2\myfile.zzz'); //S ='C:\DIR1\DIR2' S:= ExtractFilePath( 'myfile.zzz'); //S ="

... end;

Функція ExtractShortPathName()

Функція конвертує довге ім'я файлу в DOS-формат, так званий, 8.3. Цей формат має на увазі, що ім'я файлу або папки може бути довжиною максимум 8 символів, а потім, після точки, може бути присутнім розширення імені файлу з 3-х символів. Якщо ім'я папки (файлу) має більше символів, воно буде обрізане до 8 символів.

Якщо вказаний файл або каталог не існує, то функція повертає порожній рядок. Параметр може являти собою повне ім'я файлу. Якщо вказаний файл не існує, то функція повертає порожній рядок. Приклад:

var S: string; begin

... S:= ExtractShortPathName( 'C:\Program Files\\ Accessories wordpad.exe'); //Результат: S= C:\PROGRA~1\ACCESS~1\WORDPAD.EXE ... end;

Процедура ProcessPath()

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

var Dir, S: string; // ’ я папки та імені файлу Drive: Char; //для імені диска (літери A-Z)

begin ... ProcessPath('C:\DIR1\work.txt',Drive,Dir,S); // Drive= 'C'; Dir= '\DIR1'; S='work.txt' ... end;

Функція ExtractFileDrive ()

Функція повертає назву диска, витягнуте з повного імені файлу. Якщо зазначене ім'я файлу не містить назву диска, то функція повертає порожній рядок. Для імені в UNC форматі (мережеве ім'я) повертається рядок у форматі '\\<ім ’ я сервера>\<ім'я ресурсу>'.

var S: string; begin

... S:= ExtractFileDrive( 'C:\DIR1\myfile.zzz'); //S= 'C:' ... end;

Функція ExtractFileExt ()

Функція повертає розширення файлу, ім'я якого зазначено в параметрі. Результуюча рядок включає в себе символ точки і символи рошрирення файлу. Якщо зазначене ім'я файлу не має розширення, то функція повертає порожній рядок. Приклад: var S1, S2 : string; begin

... S1:= ExtractFileExt( 'www.atrussk.ru/delphi/index.htm'); //S1='.htm' S2:= ExtractFileExt( 'c:\dir1\myfile.txt'); //S2 ='.txt' ... end;

Пишемо програму

Щоб засвоїти, як працюють ці функції, створимо новий додаток. Форму відразу перейменуйте в fMain, а проект збережіть під назвою fname в окремій папці. На форму встановіть Edit, тут буде відображатися повне ім'я файлу. Відразу під нею встановіть Label, тут буде відображатися результат роботи функцій. Очистіть текст і у Edit і Label. Нижче киньте на форму кнопку, і напиши на ній «Відкрити файл». Поруч з нею киньте OpenDialog, він нам знадобиться для відкриття файлу. Ще нижче згрупуйте 6 кнопок, на яких напишіть: ExtractFileName ExtractFilePath ExtractShortPathName ExtractFileDir ExtractFileDrive ExtractFileExt

Рис. 14.1. Зовнішній вигляд програми

Створіть обробник для кнопки «Відкрити файл». Тут ми напишемо такий текст:

if OpenDialog1.Execute then begin

Edit1.Text := OpenDialog1.FileName; //записуємо адресу та ім'я відкритого файлу

Label1.Caption := Edit1.Text; //копіюємо теж саме в Labelend; //if

Далі по черзі пишемо обробники для решти кнопок. Натисніть першу, і напишіть: Label1.Caption := ExtractFileName(Edit1.Text); //змінюємо ім'я файлу Для другої кнопки:

Label1.Caption := ExtractFilePath (Edit1.Text);

Інші кнопки обробляються також - просто підставте зазначену на кнопці функцію, решті код залишається без змін. Збережіть і зберіть приклад, подивіться, як він працює.

Лекція 15. Перетворення типів

Перетворення типів

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

‘123456,78’

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