Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
Візуальне програмування
при обєктно-орієнтованому підході
до виконання лабораторних робіт з дисципліни
“Обєктно-орієнтоване програмування”
для студентів базового напрямку "Програмна інженерія"
Затверджено
на засіданні кафедри
програмного забезпечення.
Протокол № ___ від ______ 2009 р.
Львів-2009
Візуальне програмування при обєктно-орієнтованому підході: Методичні вказівки до виконання лабораторних робіт з дисципліни “Обєктно-орієнтоване програмування” для студентів базового напрямку “Програмна інженерія” / Укл.: Т. О. Коротєєва, Р. Б. Тушницький, Т. О. Муха. Львів: Видавництво Національного університету “Львівська політехніка”, 2009.
54 с.
Укладачі Коротєєва Т.О., канд. техн. наук, доц.,
Тушницький Р.Б., асист.,
Муха Т.О., асист.
Відповідальний за випуск Левус Є.В., канд. техн. наук, доц.
Рецензенти Мельник Р.А., д-р. техн. наук., проф.,
Муха І.С., канд. техн. наук, доц.
Вступ
Методичні вказівки містять теоретичні відомості стосовно основних понять візуального програмування, приклади використання базових компонент Borland C++ Builder 6, а також контрольні питання та завдання до лабораторних занять.
Метою виконання лабораторних завдань студентами є освоєння середовища розробки програмного забезпечення, в той же час поглиблення знань з фундаментальних понять програмування та теорії обчислювальних процесів та структур.
Методичні вказівки забезпечують вивчення вступного курсу до візуального програмування і рекомендуються для початківців у цій галузі програмування. Назви службових слів для наглядного сприйняття текстів виділено жирним шрифтом.
Лабораторна робота № 1
Тема. Ознайомлення із середовищем розробки Borland C++ Builder 6. Створення проекту та налаштування його властивостей.
Мета. Засвоїти принцип візуального програмування шляхом створення та налаштування проекту.
Теоретичні відомості.
Інтерфейс Borland C++ Builder називають середовищем швидкої розробки застосувань RAD (Rapid Application Development) або середовищем візуальної розробки. Таку назву цей інтерфейс отримав за те, що створення застосування в ньому зводиться в основному до простого конструювання вікна майбутнього застосування із набору готових компонент, а більшу частину стандартних операцій виконує компютер.
1.1. Огляд cередовища розробки Borland C++ Builder 6. Середовище C++ Builder умовно розділяють на наступні частини: вікно інспектора обєктів (Object Inspector) (рис. 1, а), вікно дерева обєктів (Object TreeView) (рис. 1, б), вікно класів (рис. 1, в), палітра інструментів
(рис. 1, г), вікно редактору коду (рис. 1, д), дизайнер форми (рис. 1, е).
Палітра інструментів містить закладки із набором компонент. Виділяють візуальні (видимі при запуску застосування) та невізуальні компоненти. Окрім стандартних компонент є можливість імпортувати компоненти сторонніх розробників, або створити власну компоненту.
Інспектор обєктів містить в собі закладку властивостей (Properties, рис. 2, а) та подій (Events, рис. 2, б). Призначення інспектора обєктів редагування властивостей обєктів (форм та компонент) під час розробки застосування. З його допомогою можна вказати початкове значення обєктів та присвоїти обробники подій. Властивості та події, що дозволяють звязати інші компоненти із поточною, в інспекторі обєктів виділено червоним коліром.
Рис. 1. Інтерфейс Borland C++ Builder 6:
а вікно інспектора обєктів (Object Inspector),
б вікно дерева обєктів (Object TreeView), в вікно класів,
г палітра інструментів, д вікно редактору коду, е вікно форми (Form)
а б
Рис. 2. Інспектор обєктів (Object Inspector):
а закладка властивостей (Properties), б закладка подій (Events)
У верхній частині вікна інспектора розміщено поле вибору обєктів, в якому відображається назва вибраного обєкта. Для вибору нового обєкта потрібно відкрити випадаючий список, вибравши кнопку із стрілкою, а потім необхідний обєкт із списку. Після цього можна редагувати властивості вибраного обєкта. Інший спосіб вибору обєкта клік мишкою на обєкті у формі. Третій спосіб полягає у виборі потрібного обєкту за назвою у вікні дерева обєктів (Object TreeView) (рис. 3).
Рис. 3. Дерево обєктів (Object TreeView)
Вікно дерева обєктів містить назви всіх компонент, розміщених на поточній формі.
На закладці властивостей інспектора обєктів розміщено всі неприховані властивості вибраного обєкту. Зліва відображається назва властивості, а справа її значення. Властивості можуть бути вкладені із позначенням «+» в квадраті лівіше назви властивості. Для їх розкриття необхідно клікнути на даному плюсу.
На закладці подій (Events) розташовано список подій, на які може реагувати обєкт. Ця закладка дозволяє звязати обєкт із подіями, які відбуваються в момент виконання застосування. Закладка подій теж розділена на дві частини. Ліва частина містить назву події, а права назва методів їх обробки, або простіше функцій обробки. Для створення обробника подій потрібно двічі клікнути лівою кнопкою миші в правій частині навпроти назви вибраної події. При цьому зявиться вікно редактора коду, в якому автоматично створиться заготовка тексту коду обробника подій.
В результаті при виникненні події для вибраного обєкту буде виконано дану підпрограму. Наприклад, подія OnClick означає клік лівою кнопкою миші на обєкті.
1.2. Організація проекту в Borland C++ Builder 6. Проектом називається група файлів, що необхідні для створення кінцевого виконуючого застосування. Розглянемо типи файлів що входять до звичайного проекту із користувацькими вікнами на C++ Builder (див. табл. 1).
Таблиця 1. Основні файли проекту
Файл |
Призначення |
Файл проекту (Project.cpp) |
C++ Builder створює файл Project.cpp для головної функції WinMain, що ініціює програму, створює головну форму та запускає її на виконання. |
Файл опцій проекту (Project.bpr) |
Містить налаштування опцій проекту і вказівки стосовно того, які файли і з якими опціями повинні компілюватися і компонуватися в проект. Файл зберігається у форматі XML. |
Файл ресурсів проекту (Project.res) |
Двійковий файл, що містить ресурси проекту: піктограми, курсори і т.д. За замовчуванням цей файл містить тільки піктограму проекту. Він може доповнюватись за допомогою редактора зображень (Image Editor). |
Файл реалізації модуля (Unit.cpp) |
Кожній формі, що створюється, відповідає текстовий файл реалізації модуля, що використовується для зберігання коду. Розробники можуть самі створювати модулі, що не повязані з формами. |
Файл заголовку модуля (Unit.h) |
Кожній формі що створюється відповідає файл заголовку з описом класу форми. Файли заголовків можуть створюватися розробником. |
Файл форми (Unit.dfm) |
Двійковий або текстовий файл, який C++ Builder створює для зберігання інформації про форму. Розробник може проглядати цей файл або в текстовому вигляді, або у вигляді форми. Кожному файлу форми відповідає файл модуля (Unit.cpp). |
Файли резервних копій (.~bpr, .~dfm, .~cpp, .~h) |
Файли резервних копій для файлів проекту, форми, реалізації модуля і файлу заголовку відповідно. Розробник може повернутися до попереднього варіанту проекту, змінивши відповідне розширення. |
Файл, що виконується (Project.exe) |
Файл застосування, що виконується. Він є автоматичним виконуваним файлом, для роботи якого більше нічого не потрібно, крім випадків коли ви використовуєте бібліотеки, що містяться в пакетах, DLL, OCX і т.д. |
Обєктний файл модуля (Unit.obj) |
Відкомпільований файл модуля (Unit.cpp), який компонується в кінцевий .exe-файл. |
Файл відлагодження (Project.tds) |
Файл містить в собі інформацію про проект для відлагодження, окремо від ехе-файлу. Використовується у тих випадках, коли є зібраний ехе-файл і потрібно відлагодити роботу проекту у відлагоджувачі (Debuger). Щоб не пересилати всі файли, зібрані у відлагоджуваному варіанті, відсилається лише цей файл. Потім запускається відлагоджувач із опцією завантаження символів відлагодження. Щоб отримати інформацію для відлагодження із ехе-файлу і зберегти його в *.tds є спеціальна утиліта tdstrp32.exe. |
Для раціонального використання місця на диску, можна видаляти файли резервних копій, обєктні файли та файл відлагодження, оскільки компілятор створить їх за необхідності ще раз.
Вміст файлу Project.cpp:
#include <vcl.h>
#pragma hdrstop
USEFORM("Unit1.cpp", Form1);
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
Як видно з коду, створюється форма з іменем Form1, яка буде показана при запуску застосування. Користувач може програмним чином створити власні форми і в певний момент їх показати. Якщо необхідно при запуску застосування показати дві або більше форм, то ці форми можна вказати у його властивостях, або безпосередньо в коді даного файлу. Обєкт проекту Application містить низку методів та властивостей для задання загального вигляду додатку, які можна задати безпосередньо в даному файлі.
Зауважимо, що компілятор додає за замовчуванням код обробки помилок (блок try … catch) як визначених, так і невідомих.
Середовище C++ Builder володіє зручним інтерфейсом підказок (intelligence). Для виклику підказки необхідно натиснути ctrl+пробіл. Приклад відображення підказки, що містить методи та властивості обєкту Application, зображено на рис. 4.
Рис. 4. Інтерфейс підказок у середовищі Borland C++ Builder 6
1.3. Створення та збереження нового проекту. Для кожного нового проекту рекомендується створювати окрему папку для його зберігання.
1.3.1. Створення віконного проекту. Створити новий проект можна декількома способами:
1) команда File → New → Application.
2) команда File → New → Other. При виборі цієї команди відкриється вікно New Items, в якому потрібно двічі клікнути мишею на піктограмі Application (рис. 5).
В результаті створиться віконний проект, що міститиме одну користувацьку форму, заголовочний файл .h та файл коду .cpp.
а б
Рис. 5. Створення нового проекту
Файл коду Unit1.cpp має такий вигляд:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
Файл заголовку Unit1.h:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Очевидно, що в проекті може міститись тільки одна main-функція, яка розміщена в окремому файлі проекту Project.cpp.
1.3.2. Створення консольного проекту. Якщо необхідно створити застосування без використання користувацьких вікон (форм), то для цього слід виконати наступні кроки: File → New → Other, і вибрати у діалоговому вікні (рис. 5, б) Console Wizard. При цьому відкриється діалогове вікно, що зображене на рис. 6. Тут можна вибрати мову С/С++, зазначити які будуть використовуватись бібліотеки, тощо.
Рис. 6. Налаштування консольного проекту
При виборі мови С опції, що відповідають за використання бібліотек VCL, CLX будуть недоступні. Натомість опція використання декількох потоків (Multi Threaded) буде доступною. При виборі базової мови С++ опція Multi Threaded буде увімкнена завжди, і зявиться можливість обрати одну із бібліотек VCL (для створення windows-застосування) або CLX (для створення кросплатформного застосування, тобто такого яке не буде залежати від типу операційної системи). Також можна вказати вже існуючий проект.
Зауважимо, що набір компонет у бібліотеках VCL та CLX відрізняються.
В результаті створиться консольний проект із модулем unit.cpp, який буде містити звичайну функцію main:
#include <vcl.h>
#pragma hdrstop
#pragma argsused
int main(int argc, char* argv[])
{
return 0;
}
1.3.3. Збереження проекту. Перша дія, яку рекомендується виконати після створення нового проекту зберегти його. У багатовіконних застосуваннях це дозволяє одразу задати модулям імена, які використовуватимуться в програмі для взаємних посилань модулів один на одного. Якщо збереження форми не було виконане одразу, то розробнику потрібно буде спочатку посилатися на її ім'я за замовчуванням, а надалі змінювати ці посилання.
Зберегти проект можна командою File → Save All. Зручно також використовувати відповідну швидку кнопку або комбінацію клавіш Shift+Ctrl+S. При першому збереженні C++ Builder запитує у розробника ім'я файлу модуля, що зберігається, а потім ім'я файлу проекту. Треба мати на увазі, що C++ Builder не допускає однакових імен модулів і проектів. Файли модуля і головний файл проекту мають однакове розширення .срр, тому вони повинні відрізнятися іменами, щоб не затерти на диску один одного.
У подальших сеансах роботи збережений проект можна відкрити командою File → Open Project. Якщо з проектом працювали недавно, то є можливість відкрити його командою File → Reopen, або скористатися стрілкою поряд з відповідною цій команді швидкою кнопкою. В обох випадках відкриється вікно, в якому користувач має змогу вибрати потрібний файл чи проект.
1.4. Властивості проекту. Розглянемо основні налаштування проекту. Відкрити властивості проекту можна через меню Project → Options.
Закладка Forms (рис. 7, а) дозволяє вказати головну форму проекту, а також вибрати форми, які будуть створюватися автоматично разом із головною.
Закладка Application (рис. 7, б) дозволяє задати заголовок проекту, вказати файл довідки, іконку для застосування, а також задати розширення для виконавчого файлу.
Закладка Directories/Conditionals (рис. 8, а) дозволяє задати розташу-вання include-файлів (класи), бібліотек, папку, в яку буде розміщено виконавчий файл, файли бібліотек і проміжні файли.
Закладка Version Info (рис. 8, б) дозволяє задати інформацію про версію застосування, а також додаткову інформацію про розробника. Опція Language дозволяє локалізувати застосування під певну мову.
Важливою є закладка Compiler (рис. 9), що дозволяє налаштувати режим виконання програми: режим відлагодження (debug) або режим кінцевого застосування (release). У режимі відлагодження (опція Full debug) компілятор не виконує оптимізацію коду, і зберігає інформацію для відлагодження (рис. 9, а). У режимі кінцевого застосування (опція Release) компілятор виконує оптимізацію коду, внаслідок чого застосування у більшості випадків виконується швидше, а також не збирає інформацію для відлагодження (рис. 9, б). Також для обох варіантів є можливість вказати рівні допустимих помилок при компілюванні проекту.
а б
Рис. 7. Налаштування проекту
а б
Рис. 8. Додаткові налаштування проекту
Ще однією з важливих закладок є закладка Packages (рис. 10), яку можна викликати через меню Component → Install Packages. Дана закладка дозволяє встановити бібліотеки компонент, вказати які саме бібліотеки використовуються, а також опцію компонування проекту із всіма використовуваними бібліотеками (Build with runtime packages).
а б
Рис. 9. Налаштування компілятора
Рис. 10. Налаштування бібліотек
Важливість останньої опції розглянемо на такому прикладі. Створимо новий віконний проект. Збережемо його у директорії на диску. Нехай дана опція буде увімкненою. Запустимо проект на виконання (меню Run → Run, або клавіша F9). Тепер подивимось розмір виконавчого файлу. В залежності від налаштувань, він складатиме приблизно 25 kB. Тепер вимкнемо опцію і ще раз виконаємо програму. Розмір виконавчого файлу збільшився і становить тепер 396 kB. Це пояснюється тим, що у першому випадку застосування зкомпонувалося у виконавчий файл без бібліотек, які використовуються (VCL, тощо). В іншому випадку всі необхідні бібліотеки були додані до виконавчого файлу. Таким чином, якщо є необхідність виконати застосування на компютері де відсутній Borland C++ Builder, необхідно опцію вимкнути.
Зауважимо, що розмір файлу для відлагодження, який створився в процесі компонування в даному прикладі становить 2 Mb. Для раціонального використання місця на диску, його можна видалити.
Завдання для лабораторної роботи
Контрольні питання
Лабораторна робота № 2
Тема. Базові візуальні компоненти Borland C++ Builder 6. Створення проекту із використанням візуальних компонент.
Мета. Створити віконний проект та продемонструвати використання візуальних компонент Borland C++ Builder.
Теоретичні відомості.
Палітра компонент VCL бібліотеки візуальних компонент Borland C++ Builder має ряд закладок, на яких згруповані піктограми всіх доступних стандартних компонент. Крім цього, є можливість створити власну компоненту і розмістити її на закладці, імпортувати набір компонент сторонніх розробників, змінювати розташування закладок. Розглянемо базові компоненти Borland C++ Builder 6.
2.1. Компонента Label. Компонента Label (мітка, етикетка, надпис) часто використовується при написанні різноманітних застосувань для відображення тексту, надписів на формі.
Рис. 11. Вигляд і розташування компоненти Label на палітрі компонент
Для додавання компоненти на форму необхідно один раз натиснути лівою клавішею миші на цю компоненту на палітрі компонент, розміщених на закладці Standard (рис. 11), і після цього один раз клікнути мишею в тому місці на формі, де потрібно її розмістити. Після цього на формі зявиться мітка із написом та імям за замовчуванням (рис. 12).
Рис. 12. Вигляд компоненти Label на формі
Переміщення компоненти на формі відбувається за допомогою миші або клавіш навігацій (вліво, вправо, вниз, вгору) із натисненням клавіші Ctrl.
Усі компоненти і сама форма є обєктами того чи іншого класу, який має свої методи, поля і властивості. Тому зрозуміло, що поведінка і вигляд компонент визначається їх властивостями, методами та подіями, на які вони можуть реагувати.
Доступ до властивостей на етапі проектування здійснюється за допомогою інспектора обєктів (Object Inspector), який забезпечує простий і зручний інтерфейс для зміни властивостей обєктів C++ Builder. Значення властивостей, встановлених на етапі проектування, відповідають за те, з якими початковими параметрами почне працювати застосування. До властивостей можна доступатися і на етапі його виконання, зокрема зчитувати та встановлювати їх значення.
Вікно інспектора об'єктів має дві закладки властивості та події (рис. 13). Над ними розташований випадаючий список всіх компонент, що розміщені на формі. За його допомогою є можливість вибрати потрібну компоненту.
Рис. 13. Вигляд інспектора обєктів
Текст, що відображається в компоненті Label, визначається значенням її властивості Caption. Його можна встановлювати в процесі проектування в інспекторі обєктів, ввівши довільний текст поруч з написом Caption (рис. 4), або задавати і змінювати програмно під час виконання застосування, наприклад:
Label1->Caption = "Новий текст";
Доступ в коді до властивостей і методів здійснюється наступним чином: спочатку записують назву обєкту (наприклад, Label2), потім символи «->», далі імя властивості чи методу.
Наприклад:
Label2->Visible = true;
Властивість Caption має тип рядка AnsiString. При присвоєнні цьому типові числової інформації відбувається її автоматичне перетворення в рядок. Тому є можливість безпосередньо здійснювати подібні присвоєння. Наприклад, оператор
Label1->Caption = 5.1;
приведе до появи в мітці напису «5.1». Якщо необхідно занести в мітку змішану інформацію, що складається з рядків символів і чисел, можна скористатися функціями FloatToStr і IntToStr, що перетворюють відповідно числа з плаваючою комою і цілі в рядок. Для формування тексту, що складається з декількох фрагментів, можна використати операцію "+", яка для рядків означає їх склеювання (конкатенацію). Наприклад, якщо в програмі є ціла змінна i, що відображає кількість робітників деякої організації, то вивести цю інформацію в мітку Label1 можна операторами:
Label1->Caption = "Кількість робітників: " + IntToStr(i);
Колір фону задається властивістю Color. Якщо його не задати, він буде мати значення за замовчуванням і зливатиметься з кольором контейнера, що містить мітку.
Важливою властивістю є Name. При додаванні нової компоненти на форму C++ Builder призначає їй імя за замовчуванням у вигляді: <Назва компоненти><порядковий номер> (наприклад, Label2). Рекомендується одразу ж після додавання компоненти на форму змінити її назву на таку, яка має смислове навантаження. Якщо спочатку не задати логічну назву якійсь компоненті, то надумавши зробити це пізніше необхідно буде змінити всі звертання в коді, які використовують стару назву, яка була призначена за замовчуванням. Змінити назву компоненти можна знову ж таки, як в режимі проектування так і в коді. Для зміни назви в режимі проектування ви повинні ввести нову назву у полі інспектора обєктів поруч з властивістю Name.
Колір напису визначається підвластивістю Color властивості Font. В інспекторі обєктів праворуч від властивості Font є зображення хрестика, натиснувши на яке, розкривається список підвластивостей. Якщо ж натиснути на зображенні трьох крапок ліворуч властивості Font, то відкриється діалогове вікно, в якому можна у звичний спосіб задати параметри шрифту.
Розміщення всіх візуальних компонент на формі визначається, зокрема, властивостями Left, Top, Height, Width, що представляють координати верхнього лівого кута компоненти (x, y), висоту і ширину компоненти відповідно.
Компонента Label, як і всі інші візуальні компоненти має властивість Visible, яка відповідає за відображення компоненти на формі. Якщо властивість Visible встановлена в false, то компонента є видима під час проектування, однак стає невидимою під час виконання програми. Керувати видимістю компоненти можна і під час виконання застосування, змінюючи її властивість Visible, наприклад:
Label2->Visible = true;
2.2. Компонента Edit. Дана компонента на відміну від компоненти Label не лише відображає текст, але й дає можливість користувачу під час виконання застосування його вводити. Завдяки цьому відбувається взаємодія користувача із застосуванням під час його виконання. Розміщена дана компонента на закладці Standard (рис. 14).
Рис. 14. Вигляд і розташування компоненти Edit на палітрі компонент
Додавання на форму компоненти Edit (вікна редагування) відбувається аналогічно до додавання на форму компоненти Label. При розміщенні на формі компонента має вигляд подібний до того, як зображено на рис. 15.
Текст, що вводиться і відображається у компоненті, міститься у властивості Text, яка має тип Ansistring. Цю властивість можна встановлювати в процесі проектування або задавати програмно. Вирівнювання тексту неможливе, як і перенесення рядків. Текст, що не поміщається по довжині у вікно, просто посувається і користувач може переміщуватися по ньому за допомогою курсора.
Рис. 15. Вигляд компоненти Edit
Вікно редагування має багато функцій, властивих більшості редакторів. Наприклад, в ньому передбачені типові комбінації «гарячих» клавіш: Ctrl+C копіювання виділеного тексту в буфер обміну Clipboard (команда Copy), Ctrl+X вирізування виділеного тексту в буфер Clipboard (команда Cut), Ctrl+V вставка тексту з буферу Clipboard в позицію курсору (команда Paste), Ctrl+Z відміна останньої команди редагування.
Властивість MaxLength визначає максимальну довжину тексту, що вводиться. Якщо Maxlength = 0, то довжина тексту необмежена. Інше значення Maxlength вказує максимальне число символів, яке може ввести користувач.
2.3. Компоненти Button та BitBtn. Дані компоненти представляють кнопки, що є одними з найбільш використовуваними. Це зумовлено особливостями їх використання. Розміщені вони відповідно на закладці Standard (рис. 16) та Additional (рис. 17).
Рис. 16. Вигляд і розташування компоненти Button на панелі компонент
Рис. 17. Вигляд і розташування компоненти BitBtn на панелі компонент
Найбільш простою і часто використовуваною є кнопка Button. Рідше використовується кнопка BitBtn, що відрізняється можливістю відображати на її поверхні зображення. Більшість властивостей, методів і подій для цих видів кнопок однакові.
Основна властивість кнопки Caption (напис). У написах кнопок можна передбачати використання клавіш прискореного доступу, виділяючи для цього один з символів напису. Перед символом, який повинен відповідати клавіші прискореного доступу, ставиться символ амперсанда "&". Цей символ не відображається у написі, однак наступний за ним символ стає підкресленим. Тоді користувач має змогу замість клікання на кнопку натискати у будь-який момент клавішу Alt спільно з клавішею виділеного символу.
Основне застосування кнопки повязане з можливістю її натиснення. Це забезпечується таким механізмом як подія. Події дозволяють класу або обєкту повідомити інші класи чи обєкти, про те, що відбулося «щось цікаве». Говорять, що клас, який посилає повідомлення про подію, її породжує (raise), а клас, який її приймає її отримує (handle).
При взаємодії користувача із програмою програма реагує на дії користувача за допомогою подій, які можуть породжуватись тими чи іншими обєктами (наприклад кнопками).
Закладка подій (Events) складає другу частину інспектора обєктів. На ній відображені всі події, на які може реагувати вибраний обєкт. Наприклад, якщо треба виконати певні дії у момент створення форми (зазвичай це різноманітні операції налаштування), то потрібно виділити подію OnCreate. Поряд з імям цієї події відкриється вікно з випадаючим списком. Якщо ви вже написали в своєму застосуванні обробники подій і хочете при події OnCreate використовувати один з них, ви можете вибрати необхідний обробник з випадаючого списку (рис. 18).
Якщо потрібно написати новий обробник, то зробіть подвійне клікання на порожньому вікні списку. Ви попадете у вікно Редактора коду, в якому побачите заготовку компілятора:
void fastcall TForm1::FormCreate(TObject *Sender)
{
}
Курсор буде розташований в порожньому рядку між рядками з відкриваючою і закриваючою фігурними дужками. Код, який ви побачите це заготовка обробника події, яку автоматично зробив C++ Builder. Вам залишається лише в проміжку між дужками "{" і "}" написати необхідні оператори (рис. 19).
Рис. 18. Вигляд закладки подій (Events) Інспектора обєктів,
коли ще немає жодного обробника
Рис. 19 Вигляд описаного вище коду
Рис. 20. Вигляд закладки Events Інспектора обєктів
після виконання вищеописаних дій
Якщо ви зробили ці операції, то поверніться в Інспектор обєктів, виділіть у ньому, наприклад, подію OnActivate і натисніть кнопку випадаючого списку. Ви побачите в цьому списку введений вами раніше обробник події OnCreate (рис. 20). Якщо треба використовувати той же обробник і в події OnActivate, просто виберіть його із списку. Таким чином є можливість уникнути дублювання в програмі одних і тих же фрагментів коду.
Основна подія будь-якої кнопки OnClick. Вона виникає при кліканні мишею на кнопці під час виконання програми. Саме у обробнику цієї події записуються оператори, які повинні виконуватися при кліканні користувача на кнопку. Окрім цього є ще ряд подій, повязаних з різними маніпуляціями клавішами і кнопками миші та іншими.
Якщо значення властивості Cancel встановити в true, це означатиме, що натиснення користувачем клавіші Esc буде еквівалентне кліканню по даній кнопці. Цю властивість доцільно задавати рівною true для кнопок "Відмінити" в різних діалогових вікнах для того, щоб можна було вийти з діалогу, натиснувши або на цю кнопку, або клавішу Esc.
Якщо властивість Default встановлена в true, то це означає, що натиснення користувачем клавіші введення Enter буде еквівалентне натисненню на дану кнопку, навіть якщо дана кнопка у цей момент не знаходиться у фокусі. Однак, це спрацює лише у випадку якщо у фокусі знаходиться якийсь віконний компонент. Якщо ж у момент натиснення Enter у фокусі знаходиться інша кнопка, то все-таки спрацює кнопка, яка знаходиться у фокусі. Якщо властивість Default задана рівною true в декількох кнопок на формі, то при натисненні Enter спрацює та з них, яка в послідовності табуляції є найпершою.
З методів, якими володіють кнопки, відзначимо один Click. Виконання цього методу еквівалентне кліку на кнопці, тобто викликає подію кнопки OnClick. Цим можна скористатися, щоб продублювати якимись іншими діями користувача клік на кнопці. Наприклад, потрібно, щоб при натисненні користувачем клавіші з символом "С" або "с" у будь-який момент роботи з застосуванням виконувалися операції, передбачені в обробнику події OnClick кнопки Button1. Оскільки невідомо, який компонент буде знаходитись у фокусі у момент цієї події, треба перехопити його на рівні форми. Таке перехоплення здійснюється, якщо встановити властивість форми KeyPreview у true. Тоді в обробнику події форми OnKeyPresss можна написати оператори:
if ((Кеу == 'С') || ( Кеу == 'с')) Button1->Click();
Якщо користувач ввів символ "С" або "с", то в результаті буде виконаний обробник натиснення кнопки Button1.
Все сказане вище в рівній мірі відноситься і до Button, і до BitBtn. Розглянемо тепер особливості кнопки з піктограмою BitBtn. Зображення на цій кнопці задається властивістю Glyph. При натисненні кнопки з трьома крапками у рядку властивості Glyph в інспекторі обєктів відкриється вікно, представлене на рис. 21.
Рис. 21. Робота із властивістю Glyph компоненти BitBtn
Натиснувши кнопку Load, ви перейдете в звичайне вікно відкриття файлу малюнка, де зможете вибрати файл бітової матриці .bmp, що містить бажане зображення. Вибравши потрібне зображення і натиснувши кнопку ОК вибране зображення зявиться на вашій кнопці лівіше за напис.
Приклад. Проілюструємо можливості використання і принцип роботи із розглянутими компонентами. Створимо форму наступного вигляду:
Рис. 22. Вигляд форми в режимі проектування та в роботі застосування
Для цього створимо новий віконний проект і на форму помістимо дві мітки, два вікна редагування і одну кнопку. Властивості Caption міток задамо значення "x" та "y" відповідно, кнопки "Натисни". Значення властивостей Text вікон редагування видалимо, тим самим задавши їм значення пустих стрічок. Створимо обробник події OnClick для кнопки. Для цього виберемо кнопку на формі одним кліком миші по ній, і після цього в інспекторі обєктів в закладці Events клікнемо двічі поруч в полі поруч з відповідною подією. В заготовці обробника події введемо наступний код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Randomize();
Button1->Top = random(Form1->ClientHeight - Button1->Height);
Button1->Left = random(Form1->ClientWidth - Button1->Width);
Edit1->Text = Button1->Top;
Edit2->Text = Button1->Left;
}
Функція Randomize() ініціалізує початкове значення генератора випадкових чисел.
Функція int random(int) повертає випадкове значення більше за нуль, але менше за число в дужках.
Застосування при кожному натисканні на кнопку переміщає її у випадковим чином вибрану позицію, при цьому нові координати кнопки відображаються у значеннях Edit1 та Edit2. Як бачимо, це все відбувається завдяки доступу до відповідних властивостей та їх зміни.
Тепер добавимо обробник події OnMouseMove для кнопки Button1:
void __fastcall TForm1::Button1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
Randomize();
Button1->Top = random(Form1->ClientHeight - Button1->Height);
Button1->Left = random(Form1->ClientWidth - Button1->Width);
Edit1->Text = Button1->Top;
Edit2->Text = Button1->Left;
}
Для кнопки змінимо властивість TabStop = false і внесемо зміни в код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShowMessage("Вітання! Ви перемогли!");
}
Якщо користувач натисне кнопку буде показано повідомлення із текстом «Вітання! Ви перемогли!». Однак кнопка щоразу змінюватиме свою позицію на формі як тільки користувач підведе курсор миші до неї це забезпечується подією OnMouseMove.
2.4. Компоненти CheckBox і CheckListBox. Індикатори з прапорцем CheckBox використовуються в застосуваннях в основному для того, щоб користувач мав змогу вмикати і вимикати певні опції, або для індикації стану. Дана компонента розташована на закладці Standard (рис. 23).
Рис. 23. Розташування на палітрі піктограми компоненти CheckBox
При кожному кліку користувача на індикаторі його стан змінюється, проходячи в загальному випадку послідовно через три значення: виділене (поява чорної галочки), проміжне (сіре вікно індикатора і сіра галочка) і не виділене (порожнє вікно індикатора). Цим трьом станам відповідають три значення властивості State: cbChecked, cbGrayed, cbUnchecked. Проте, ці три стани допускаються лише при значенні іншої властивості AllowGrayed рівному true. Якщо ж AllowGrayed = false (значення за замовчуванням), то допускається лише два стани: виділене і не виділене. І State, і AllowGrayed можна встановлювати під час проектування або програмно під час виконання.
Проміжний стан зазвичай використовується, якщо індикатор застосовується для відображення якоїсь характеристики обєкту. Наприклад, якщо індикатор покликаний показати, який регістр використовувався при написанні якогось фрагмента тексту, то у випадку, якщо весь текст написаний у верхньому регістрі, індикатор може приймати виділений стан, якщо в нижньому не виділений, а якщо використовувалися обидва регістри проміжний.
Перевіряти стан індикатора можна не лише за значенням State, але і за значенням властивості Checked. Якщо Checked рівне true, то індикатор вибраний, тобто State = cbChecked. Якщо властивість Checked рівна false, то State рівне cbUnchecked або cbGrayed. Встановлення Checked у true під час проектування або виконання автоматично перемикає State у cbChecked.
У індикаторі CheckBox напис задається властивістю Caption, а її розміщення по відношенню до індикатора властивістю Alignment.
Ще одна компонента, що має індикатори список CheckListBox. У ній біля кожного рядка списку є індикатор, стан якого користувач може змінювати. Дана компонента розташована на закладці Additional (рис. 24). Стани індикаторів визначають дві властивості: State і Checked, які можна розглядати як індексовані масиви, кожен елемент якого відповідає індексу рядка. Загальна кількість елементів визначається властивістю Count (лише для читання). Оскільки індекси починаються з 0, то індекс останнього елементу рівний Count - 1.
Рис. 24. Розташування піктограми компонента CheckListBox
Властивості State і Checked можна встановлювати. Наприклад, оператори
CheckListBoxl->Checked[l] = true;
CheckListBoxl->State[2] = cbGrayed;
встановлюють індикатор другого рядка списку CheckListBox1 у стан вибраного, а індикатор третього рядка в проміжний стан (пригадаємо, що індекси починаються з 0).
Наступні оператори перевіряють стан всіх індикаторів списку, і для вибраних користувачем рядків здійснює певні дії (на місці цих дій поставлено три крапки):
for (int i = 0; i < CheckListBox1->Items->Count; i++)
if (CheckListBox1->Checked[i])
{ ... }
У компоненті CheckListBox є також подія OnClickCheck, яка виникає при кожній зміні користувачем стану індикатора. Це можна використовувати для обробки результатів зміни.
2.5. Компонента CspinEdit. CSpinEdit це компонента, в якій користувач може вибирати ціле число, змінюючи його кнопками із стрілками.
За значення, яке відображається у компоненті CSpinEdit відповідає властивість Value. Її можна встановлювати під час проектування, і можна до неї доступатися в коді, змінюючи її необхідним чином. Дана компонента розміщена на закладці Samples (рис. 25).
Рис. 25. Розташування на палітрі інструментів компоненти CspinEdit
При натисканні на стрілки компоненти значення, яке відображається в ній збільшується або зменшується на 1, в залежності від того, яку стрілку натиснули. За крок, на який змінюється значення в CSpinEdit відповідає властивість Increment.
Компонента CSpinEdit дає змогу обмежити максимальне та мінімальне можливе значення, задавши MaxValue і MinValue. При цьому при досягненні верхньої або нижньої межі компонента не дасть змоги ще збільшити або зменшити значення. Якщо значення цих двох властивостей, тобто MaxValue і MinValue, однакові, то вважається, що обмежень на значення немає.
Завдання для лабораторної роботи
3. Реалізувати калькулятор.
Контрольні питання
Лабораторна робота № 3
Тема. Огляд невізуальних компонент Borland C++ Builder 6. Створення проекту із невізуальними компонентами та їх використання.
Мета. Створити віконний проект та продемонструвати використання невізуальних компонент C++ Builder.
Теоретичні відомості.
Невізуальні компоненти це компоненти які є невидимі при виконанні застосування, а у режимі конструювання зображаються іконкою. Такі компоненти можна розміщати в будь-якому місці форми. Розглянемо роботу з базовими невізуальними компонентами C++ Builder.
3.1. Системні діалоги. До невізуальних компонент належать 10 діалогів із закладки Dialogs: OpenDialog, SaveDialog, OpenPictureDialog, SavePictureDialog, FontDialog, ColorDialog, PrintDialog, PrinterSetupDialog, FindDialog, ReplaceDialog (рис. 26). При звертанні до цих компонент викликаються стандартні діалоги, вигляд яких залежить від версії Windows і налаштувань системи.
Рис. 26. Закладка Dialogs: 1 OpenDialog, 2 SaveDialog,
3 OpenPictureDialog, 4 SavePictureDialog, 5 FontDialog, 6 ColorDialog,
7 PrintDialog, 8 PrinterSetupDialog, 9 FindDialog, 10 ReplaceDialog
Виклик діалогу здійснюється за допомогою методу Execute, який повертає значення true якщо користувач здійснив певний вибір. При цьому у властивостях компоненти зберігається вибір користувача, який можна в подальшому використовувати. Якщо користувач натиснув кнопку «Відміна» або клавішу Esc, то функція Execute поверне false. В загальному вигляді звертання до метода Execute має вигляд:
if (<імя компоненти-діалога> -> Execute())
{ . . . }
OpenDialog. Цей діалог призначений для створення вікна діалогу «відкрити файл». Клас TOpenDialog показує модальне Windows вікно для вибору та відкриття файлів (рис. 27). Діалог не показується доки він не буде викликаний методом Execute. Коли користувач натисне кнопку «Відкрити» («Open»), діалог закривається, і вибраний файл або множина файлів зберігається у властивості Files. Типи файлів, які зявляються у випадаючому списку діалога задаються властивістю Filter. В процесі проектування зручно задати типи файлів з допомогою редактора фільтрів, який викликається кліком мишки по кнопці з трьома крапками навпроти властивості Filter (рис. 28).
Рис. 27. Діалогове вікно OpenDialog
Рис. 28. Редактор фільтрів
У ньому в колонці Filter Name задається імя фільтра, що буде показуватися у випадаючому списку діалога, а у Filter розділені символом «;» шаблони, за якими відбиратимуться файли. Наприклад:
Текстові файли (*.txt, *.doc, *.rtf) *.txt; *.doc; *.rtf
Після задання шаблону з рис. 28 у властивості Filter зявиться стрічка вигляду:
All Files|*.*|Cpp Files|*.cpp|Text Files|*.txt
В даній стрічці тексти і шаблони розділені вертикальними лініями. Аналогічним чином можна задавати властивість Filter програмно.
Властивість Filterlndex визначає номер фільтра, який буде за замовчуванням показаний користувачу при відкритті діалогу. Властивість InitialDir визначає початковий каталог, який буде відкритий в момент початку роботи із діалогом. Якщо значення цієї властивості не задане, то відкривається поточний каталог, або той, що був відкритий при останньому звертанні користувача до відповідного діалогу в процесі виконання застосування. Властивість DefaultExt визначає значення розширення файла за замовчуванням. Якщо значення не вказано, користувач має вибрати в діалозі імя файлу із розширенням. Властивість Title дозволяє задати заголовок вікна діалогу. Властивість Options задає додаткові умови вибору файла.
SaveDialog. Цей діалог призначений для створення вікна діалогу «зберегти файл» (рис. 29). Властивості даного діалогу аналогічні до властивостей OpenDialog.
Рис. 29. Діалогове вікно SaveDialog
Наведемо приклад використання даних діалогів. Помістимо на форму компоненту для відображення багатострічкового тексту RichEdit із закладки Win32, дві кнопки Button (у властивостях Caption задамо відповідно «Відкрити» та «Зберегти»), діалоги OpenDialog та SaveDialog.
В компоненті RichEdit текст зберігається у властивості Lines. Очистимо текст в компоненті, натиснувши на кнопку «...» і видаливши текст «RichEdit1» таким чином щоб зверху був напис «0 lines» (рис. 30).
Рис. 30. Вікно редактору тексту компоненти RichEdit
Після цього форма буде мати вигляд як на рис. 31.
Рис. 31. Приклад вигляду форми із компонентами
При натисканні на кнопку «Відкрити» добавимо наступний код в обробник події OnClick:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
RichEdit1->Lines->LoadFromFile(OpenDialog1->FileName);
}
}
При натисканні кнопки «Відкрити» і виборі файлу, його вміст відображається у компоненті RichEdit (рис. 32).
Рис. 32. Форма із відкритим текстовим файлом
При натисканні на кнопку «Зберегти» добавимо наступний код в обробник події OnClick:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (SaveDialog1->Execute())
{
RichEdit1->Lines->SaveToFile(SaveDialog1->FileName);
}
}
На відміну від розглянутих компонент OpenDialog і SaveDialog, компоненти OpenPictureDialog та SavePictureDialog мають додаткові можливості попереднього перегляду графічних файлів (рис. 33).
Рис. 33. Діалогове вікно OpenPictureDialog
В цих діалогах за замовчуванням вказано фільтри, в яких перелічені всі графічні файли, з якими може працювати діалог (рис. 34).
Рис. 34. Фільтри за замовчуванням компоненти OpenPictureDialog
Компонента FontDialog викликає діалогове вікно вибору атрибутів шрифта (рис. 35). В ньому користувач може вибрати імя шрифта, його стиль, розмір та інші атрибути. Основна властивість компоненти Font типу TFont, в якому можна задати початкові налаштування атрибутів шрифта, і зчитати значення атрибутів, задані користувачем в процесі діалога.
Рис. 35. Діалогове вікно FontDialog
Властивості MaxFontSize і MinFontSize встановлюють обмеження на максимальний і мінімальний розміри шрифта. Якщо значення цих властивостей рівне 0 (значення за замовчуванням), то обмежень немає. Дані властивості працюють лише при увімкненій опції fdLimitSize.
Властивість Device визначає, з якого списку можливих шрифтів буде запропоновано вибір в діалоговому вікні: fdScreen із списка екрану (за замовчуванням), fdPrinter із списка принтера, fdBoth з обох.
Приклад використання діалового вікна FontDialog:
if (FontDialog1->Execute())
{
Button1->Font->Assign(FontDialog1->Font);
}
В результаті виконання застосування, вибрані користувачем атрибути шрифта будуть присвоєні кнопці Button1. Якщо потрібно змінити шрифт всіх компонент і надписів на формі, то це можна здійснити наступним чином:
if (FontDialog1->Execute())
{
Font->Assign(FontDialog1->Font);
}
Компонента ColorDialog викликає діалогове вікно вибору кольору (рис. 36, а). В ньому користувач може вибрати колір із базової палітри або натиснувши кнопку «Визначити колір» («Determine color») визначити власний (рис. 36, б).
а б
Рис. 36. Діалогове вікно ColorDialog
Основна властивість компоненти ColorDialog Color. Дана властивість відповідає кольору, який вибрав користувач у діалозі. Приклад використання компоненти:
if (ColorDialog1->Execute())
{
RichEdit1->Color = ColorDialog1->Color;
}
Діалоги друку та встановлення принтера компоненти PrintDialog і PrinterSetupDialog. Компонента PrintDialog викликає діалогове вікно друку (рис. 37), в якому користувач може вибрати принтер і встановити його властивості, вказати кількість копій і чергування їх друку, друк у файл чи безпосередньо на принтер, вибрати сторінки для друку тощо. Компонента PrintDialog не здійснює друк. Вона лише дозволяє користувачу задати атрибути друку. Сам друк повинен реалізовуватись програмно за допомогою обєкта Printer або іншим чином. На відміну від розглянутих діалогів, PrintDialog повертає низку властивостей, що характеризують вибрані користувачем налаштування (табл. 2).
Перед викликом діалога бажано визначити кількість сторінок у друкованому тексті, і задати властивості MaxPage і MinPage. У протилежному випадку користувачу буде недоступна опція Сторінки з ... по ... (Pages from … to … )(рис. 37).
Рис. 37. Діалогове вікно PrintDialog
Таблиця 2. Властивості що повертає PrintDialog
PrintRange |
Вказує вибрану користувачем радіокнопку з групи Друкувати: prAllPages вибрана кнопка Всі сторінки, prSelection вибрана кнопка Сторінки з ... по ... , prPageNums вибрана кнопка Сторінки. |
FromPage |
Вказує встановлену користувачем початкову сторінку у вікні Сторінки з ... по ... |
ToPage |
Вказує встановлену користувачем кінцеву сторінку у вікні Сторінки з ... по ... |
PrintToFile |
Вказує чи вибраний користувачем індикатор Друк у файл. |
Copies |
Вказує встановлену кількість копій. |
Collate |
Вказує чи вибраний користувачем індикатор Розібрати. |
Компонента PrinterSetupDialog викликає діалогове вікно встановлення принтера. Це єдина діалогова компонента, що не має жодних специфічних властивостей, які потрібно встановлювати або читати. Діалог виконує операції по встановленню принтера, на якому буде відбуватися друк, і заданні його налаштувань. Цей діалог не повертає жодних параметрів (рис. 38).
Рис. 38. Діалогове вікно PrinterSetupDialog
Виклик даного діалогу відбувається наступним чином:
PrinterSetupDialog1->Execute();
Компоненти FindDialog (рис. 39) і ReplaceDialog (рис. 40) викликають діалогові вікна пошуку та заміни фрагмента текста. Компонента ReplaceDialog похідний клас від FindDialog, тому ці діалоги дуже подібні і мають однакові властивості крім однієї, що задає текст в компоненті ReplaceDialog.
Рис. 39. Діалогове вікно FindDialog
Рис. 40. Діалогове вікно ReplaceDialog
Компоненти мають наступні основні властивості: FindText текст, заданий користувачем для пошуку чи заміни, ReplaceText (тільки в компоненті ReplaceDialog) текст, який повинен заміняти FindText, Options додаткові властивості.
Самі по собі компоненти FindDialog і ReplaceDialog не здійснюють ні пошуку ні заміни. Вони лише забезпечують інтерфейс з користувачем. Пошук і заміну потрібно здійснювати програмно. Для цього можна використати подію OnFind, яка відбувається коли користувач натиснув в діалозі кнопку Найти далее і подією OnReplace, що виникає коли користувач натиснув кнопку Заменить або Заменить все. В події OnReplace визначити яку саме кпонку натиснув користувач можна за значеннями прапорців frReplace та frReplaceAll.
3.2. Компонента Timer. Дана компонента розміщена на закладці System і дозволяє задавати у застосуваннях інтервали часу (рис. 41). Компонента має дві властивості: Interval інтервал часу в мілісекундах і Enabled доступність.
Рис. 41. Розташування на палітрі піктограми компоненти Timer
Властивість Interval задає період спрацьовування таймера. Через заданий інтервал часу після попереднього спрацьовування, або після програмного встановлення властивості Interval, або після запуску застосування, якщо значення Interval встановлене під час проектування, таймер спрацьовує, викликаючи подію OnTimer. В коді обробника цієї події записують необхідні оператори. Якщо задати Interval = 0 або Enabled = false, то таймер перестане працювати. Щоб запустити відлік часу потрібно задати Enabled = true, якщо встановлено додатнє значення Interval, або задати додатнє значення Interval, якщо встановлено значення властивості Enabled = false.
Наприклад, якщо необхідно, щоб через 5 секунд після запуску застосування закрилась форма-заставка, що відображає логотип застосування, потрібно на ній розмістити таймер, задати в ньому інтервал Interval = 5000, а в обробнику події OnTimer вставити оператор Close, що закриває форму.
Якщо необхідно в деякій процедурі запустити таймер, який відрахує заданий інтервал, наприклад 5 секунд, після чого потрібно виконати деякі операції і відключити таймер, то можна це зробити наступним чином. При проектуванні таймер зробити доступним (Enabled = true), але властивість Interval задати рівною 0. Таймер не буде працювати, доки в момент, коли потрібно запустити таймер не виконається оператор
Timer1->Interval = 5000;
Через 5 секунд після цього наступить подія OnTimer. В коді її обробника потрібно задати оператор
Timer1->Interval = 0;
який відключить таймер, після чого можна виконувати потрібні операції.
Другий еквівалентний спосіб вирішення цієї задачі це використання властивості Enabled. Під час проектування задається значення Interval = 5000 і значення Enabled = false. В момент, коли потрібно запустити таймер виконується оператор
Timer1->Enabled = true;
В коді обробника події OnTimer, яка наступить через 5 секунд після запуску таймера, можна вставити оператор
Timer1->Enabled = false;
який відключить таймер.
Таймер точно витримує задані інтервали Interval, якщо вони достатньо великі соті і тисячні мілісекунд. Якщо ж задавати менші інтервали, то реальні інтервали часу будуть помітно більшими внаслідок різних накладних витрат, повязаних із викликами функцій та іншими обчислювальними аспектами.
3.3. Компоненти MainMenu і PopupMenu. У C++ Builder є дві компоненти, що представляють меню: MainMenu головне меню, і PopupMenu контекстне меню (рис. 42). Компоненти розміщені на закладці Standard і мають багато спільного.
Рис. 42. Розташування на палітрі піктограм компонент MainMenu та PopupMenu
Дані компоненти є невізуальними, тобто їх розміщення на формі під час проектування немає значення (рис. 43).
Рис. 43. Розташування компонент MainMenu та PopupMenu на формі
Зазвичай на форму розміщають одну компоненту MainMenu. В цьому випадку її імя автоматично заноситься у властивість форми Menu. Але можна помістити на форму декілька компонент MainMenu із різними наборами розділів, що відповідатимуть різним режимам роботи. В такому випадку, якщо потрібно переключитись на меню MainMenu2, потрібно написати оператори:
Form1->Menu = MainMenu2;
Основна властивість компоненти Items. Її заповнення відбувається з допомогою конструктора меню, яке викликається подвійним кліком мишкою по компоненті або вибором кнопки «...» поруч із властивістю Items у вікні інспектора обєктів. В результаті відкриється вікно, зображене на рис. 44. За допомогою цього конструктора можна спроектувати все меню.
Рис. 44. Конструктор меню для MainMenu
Назву розділа меню вказують у властивості Caption. Після цього вона автоматично зявляється на формі та у конструкторі. Тут є можливість задати іконки для підменю (при цьому має бути в наявності контейнер для піктограм ImageList), створити багаторівневі підменю, розділювачі меню (слід вказати символ «-» у властивості Caption) тощо. Властивість Name задає імя обєкта. Рекомендується вибирати змістовні імена для обєктів. Основна подія розділу меню OnClick, в коді обробника якої записують необхідні оператори.
Для будь-якого меню під час проектування, або програмно під час виконання може бути встановлена властивість Enabled (доступність) і Visible (видимість). Якщо встановити Enabled = false, то розділ буде зображатися сірим надписом і не буде реагувати на дії користувача. Якщо задати Visible = false, то розділ взагалі буде відсутній, а інші розділи займують його місце. Дані властивості використовують для того, щоб програмно змінювати доступні користувачу розділи меню в залежності від режиму роботи застосування.
Аналогічним чином можна спроектувати контекстне меню, викликавши конструктор меню для PopupMenu (рис. 45). Контексне меню привязане до конкретних компонент. Воно вспливає, коли даний компонент є у фокусі і користувач клікне правою кнопкою миші. Оскільки в застосуванні може бути декілька контекстних меню, то і компонент PopupMenu може бути декілька.
Привязати контексне меню можна під час проектування і програмно, задавши компоненті властивість PopupMenu (рис. 46).
Рис. 45. Конструктор меню для PopupMenu
Рис. 46. Приєднання компонент до форми та їх вигляд при роботі застосування
Завдання для лабораторної роботи
Контрольні питання
Лабораторна робота № 4
Тема. Компоненти Borland C++ Builder 6 для представлення даних.
Мета. Створити віконний проект та продемонструвати використання компонент призначених для відображення та опрацювання даних.
Теоретичні відомості.
Середовище розробки Borland C++ Builder має набір компонент які призначені для відображення, редагування, розміщення та опрацювання даних. Найпростіший спосіб відобразити дані представити їх у вигляді таблиці. Для цього у Borland C++ Builder 6 є компонента StringGrid.
4.1. Компонента StringGrid. Компонента StringGrid (рис. 47, 48) є таблицею, що містить рядки. Дані таблиці можуть бути лише для читання або такими, що можуть бути редаговані. Таблиця може мати смуги прокрутки, причому задане число перших рядків і стовпців може бути фіксованим і не прокручуватися. Таким чином, можна задати заголовки стовпців і рядків, що постійно присутні у вікні компоненти. Компонента призначена в першу чергу для представлення текстової інформації, однак є можливість відображати і графічну.
Рис. 47. Розташування компоненти StringGrid
Основні властивості компоненти, що відповідають за відображення текста в комірці:
System::AnsіString Cells [int ACol][int ARow] |
Рядок, що міститься у комірці з індексами стовпця і рядка ACol і ARow |
Classes::TStrings* Cols [int Index] |
Список рядків і повязаних з ними обєктів, що містяться в стовпці з індексом Index |
Classes::TStrings* Rows [int Index] |
Список стовпців і повязаних з ними обєктів, що містяться в рядку з індексом Index |
System::Tobject* Objects [int ACol][int ARow] |
Обєкт, що звязаний із рядком, що міститься в комірці з індексами стовпця і рядка ACol і ARow |
Всі ці властивості доступні під час виконання. Задавати текст можна програмно або окремими комірками, або стовпцями і рядками за допомогою методів класу TStrings.
Рис. 48. Початковий вигляд компоненти на формі
Наприклад, наступний код:
int i, j;
for (i = 1; i < StringGrid1->ColCount; i++)
StringGrid1->Cells[i][0] = "стовпець " + IntToStr(i);
for (i = 1; i < StringGrid1->RowCount; i++)
{
StringGrid1->Cells[0][i] = "стрічка " + IntToStr(i);
for (j = 1 ; j < StringGrid1->RowCount; j++)
StringGrid1->Cells[j][i] =
IntToStr(i) + ':' + IntToStr(j);
}
забезпечить заповнення елементів таблиці текстом, показаним на рис. 49.
Рис. 49. Приклад роботи із компонентою StringGrid
Властивості ColCount і RowCount визначають відповідно кількість стовпців і рядків, властивості FixedCols і FixedRows кількість фіксованих (не прокручуваних) стовпців і рядків. Колір фону фіксованих комірок задається властивістю FixedColor. Властивості LeftCol і TopRow визначають відповідно індекси першого видимого на екрані в даний момент прокручуваного стовпця і першого видимого прокручуваного рядка.
Властивість ScrollBars визначає наявність в таблиці смуг прокрутки. Смуги прокрутки зявляються і зникають автоматично залежно від того, чи поміщається таблиця у відповідний розмір компоненти, чи ні.
Властивість Options задає наступні параметри компоненти:
- наявність розділових вертикальних і горизонтальних ліній у фіксованих (goFixedVertLine і goFixedHorzLine) і не фіксованих (goVertLine і goHorzLine) комірках;
- можливість для користувача змінювати за допомогою миші розміри стовпців і рядків (goColSizing і goRowSizing);
- переміщати стовпці і рядки (goColMoving і goRowMoving) та ін.
Важливим елементом у властивості Options є goEditing можливість редагувати вміст таблиці. Якщо значення goEditing = true, то користувач має змогу змінювати вміст комірок, у протилежному випадку немає.
В основному компонента StringGrid використовується для введення користувачем певних значень, що відображуються у комірках. Властивості Col і Row показують індекси стовпця і рядка виділеної комірки. Компонента StringGrid дає змогу користувачу виділити множину комірок, рядків і стовпців.
Серед подій компоненти StringGrid слід відзначити подію OnSelectCell, що виникає у момент вибору користувачем комірки. В обробник цієї події передаються цілі параметри ACol і ARow стовпець і рядок виділеної комірки, і булевий параметр CanSelect допустимість вибору. Параметр CanSelect можна використовувати для заборони виділення комірки, задавши його значення false. Параметри ACol і ARow можуть використовуватися для певної реакції застосування на дії користувача. Наприклад, оператори:
Labell->Caption = "Вибрана комірка " + IntToStr(ARow) + ':' +
IntToStr(ACol) + ". Текст: " +
StringGridl->Cells[ACol][ARow];
виведуть в мітку Label1 повідомлення про рядок, стовпець і текст вибраної комірки (рис. 50).
Рис. 50. Вивід інформації про вибрану комірку
4.2. Створення гри із використанням базових компонент Borland C++ Builder 6. Суть гри полягає в наступному: на формі розміщено поле довільного розміру, на якому в комірках зображено числа «0». Із заданим інтервалом часу (задається рівнем гри) на полі зявляється і зникає число «1». Для перемоги гравець, маючи встановлену кількість спроб, повинен встигнути вибрати комірку із числом «1».
Для реалізації гри використаємо наступні компоненти Borland C++ Builder 6: зображення ігрового поля StringGrid, таймер Timer, для кнопки «Старт» Button, для задання рівня гри CspinEdit, для виводу допоміжної інформації компоненти Label та Edit (рис. 51).
Рис. 51. Вигляд форми в режимі проектування
Крок 1. Ініціалізація ігрового поля. Добавимо в обробник події OnActivate форми заповнення StringGrid з іменем sgGameField числами «0». Число «0» неявно буде приведене до типу AnsiString.
void __fastcall TForm1::FormActivate(TObject *Sender)
{
for(int i = 0; i < sgGameField->ColCount; i++)
{
for(int j = 0; j < sgGameField->RowCount; j++)
{
sgGameField->Cells[i][j] = 0;
}
}
}
Крок 2. Добавимо обробник події OnTimer для таймеру. Потрібно розмістити у випадковій комірці ігорового поля число «1», а попереднє число затерти «0». Значення рядка і стовпця поточної комірки, що містить «1» зберігатимемо у глобальних змінних цілого типу posi та posj, а кількість спроб у глобальній змінні цілого типу iAttempsNumber. Добавимо їх:
int posi, posj;
int iAttempsNumber;
Попереднє значення комірки з числом «1» замінимо на число «0»:
sgGameField->Cells[posi][posj] = 0;
Для вибору випадкової комірки використаємо функцію random(int value), а для ініціалізації випадкових чисел метод Randomize().
Randomize();
posi = random(sgGameField->ColCount);
posj = random(sgGameField->RowCount);
Заносимо туди число «1»:
sgGameField->Cells[posi][posj] = 1;
Залишок часу відображатиметься в полі Edit з іменем editTime. Зменшимо його на 1:
editTime->Text = editTime->Text - 1;
Крім цього здійснимо перевірку чи закінчився час або спроби: якщо в значенні поля editTime->Text != 0 і iAttempsNumber != 0, то здійснюватимемо вище описані операції щодо вставновлення числа «1» у нову випадкову комірку, інакше зупинемо таймер і виведемо відповідне повідомлення:
Timer1->Enabled = false;
if(editTime->Text == 0)
{
ShowMessage("Час вичерпано :(");
}
else
{
ShowMessage("Спроби вичерпано :(");
}
Остаточно обробник події виглядатиме наступним чином:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if(editTime->Text != 0 && iAttempsNumber != 0)
{
sgGameField->Cells[posi][posj] = 0 ;
Randomize();
posi = random(sgGameField->ColCount);
posj = random(sgGameField->RowCount);
sgGameField->Cells[posi][posj] = 1;
editTime->Text = editTime->Text - 1;
}
else
{
Timer1->Enabled = false;
if(editTime->Text == 0)
{
ShowMessage("Час вичерпано :(");
}
else
{
ShowMessage("Спроби вичерпано :(");
}
}
}
Крок 3. Добавимо обробник події OnSelectCell для StringGrid. Якщо гравець вибрав комірку, що містить число «1», то зупинемо таймер і виведемо відповідне повідомлення. Крім цього, зменшимо кількість спроб на 1:
if (sgGameField->Cells[ACol][ARow] == 1)
{
Timer1->Enabled = false;
ShowMessage("Вітання! Ви перемогли!");
}
labelAttemps->Caption = --iAttempsNumber;
Добавимо перевірку кількості спроб. Якщо iAttempsNumber != 0, то здійснимо перевірку вибраної комірки, інакше зупинемо таймер і виведемо відповідне повідомлення:
Timer1->Enabled = false;
ShowMessage("Спроби вичерпані :(");
Залишилося додати перевірку чи працює таймер: якщо таймер працює, будемо здійснювати вище описані операції, інакше очікуємо дій користувача. Остаточно код обробника події виглядає наступним чином:
void __fastcall TForm1::sgGameFieldSelectCell(
TObject *Sender, int ACol, int ARow, bool &CanSelect)
{
if (Timer1->Enabled)
{
if(iAttempsNumber != 0)
{
if (sgGameField->Cells[ACol][ARow] == 1)
{
Timer1->Enabled = false;
ShowMessage("Вітання! Ви перемогли! ");
}
Label5->Caption = --iAttempsNumber;
}
else
{
Timer1->Enabled = false;
ShowMessage("Спроби вичерпані :(");
}
}
}
Крок 4. Добавимо обробник події OnClick кнопки «Старт». Потрібно:
- попередню комірку із числом «1» замінити на число «0»:
sgGameField->Cells[posi][posj] = 0;
- задати початкове число спроб і вивести його у відповідний напис (labelAttemps) на формі:
iAttempsNumber = 10;
labelAttemps->Caption = "10";
- задати початковий проміжок часу, вказавши його на формі у полі Edit (в нашому випадку це поле із назвою editTime):
editTime->Text = 60;
- задати інтервал для таймера і включити його. Задамо наступні значення компоненти CSpinEdit1: MinValue = 1, MaxValue = 8. Тепер для кожного рівня гри визначимо інтервал часу для таймера наступним чином:
Timer1->Interval = 800 - (CSpinEdit1->Value - 1) * 100;
Timer1->Enabled = true;
Остаточно код обробника події виглядатиме наступним чином:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
sgGameField->Cells[posi][posj] = 0;
iAttempsNumber = 10;
labelAttemps->Caption = "10";
editTime->Text = 60;
Timer1->Interval = 800 - (CSpinEdit1->Value - 1) * 100;
Timer1->Enabled = true;
}
Крок 5. Додаткові налаштування. Для StringGrid встановимо наступні налаштування: FixedCols = 0, FixedRows = 0, Options->goEditing = false, Options->goRangeSelect = false.
На рис. 52, а зображено вигляд застосування при його старті, на рис. 52, б вигляд при виборі комірки із числом «1».
а б
Рис. 52. Початковий вигляд застосування (а) та вибір комірки із «1» (б)
Завдання для лабораторної роботи
Контрольні питання
Список літератури
З М І С Т
Вступ 3
Лабораторна робота № 1. Ознайомлення із середовищем розробки
Borland C++ Builder 6. Створення проекту та налаштування його властивостей. 3
Теоретичні відомості
1.1 Огляд середовища розробки Borland C++ Builder 6 3
1.2. Організація проекту в Borland С++ Builder 5
1.3. Створення та збереження нового проекту 8
1.3.1. Створення віконного проекту 8
1.3.2. Створення консольного проекту 10
1.3.3. Збереження проекту 11
1.4. Властивості проекту 11
Завдання до лабораторної роботи 14
Контрольні питання 14
Лабораторна робота № 2. Базові візуальні компоненти Borland C++ Builder 6 15
Теоретичні відомості 15
2.1. Компонента Label 15
2.2. Компонента Edit 18
2.3. Компоненти Button та BitBtn 19
2.4. Компоненти CheckBox та CheckListBox 24
2.5. Компонента CSpinEdit 26
Завдання до лабораторної роботи 27
Контрольні питання 27
Лабораторна робота № 3. Базові невізуальні компоненти Borland C++ Builder 6 28
Теоретичні відомості 28
3.1. Системні діалоги 28
3.2. Компонента Timer 38
3.3. Компоненти MainMenu і PopupMenu 39
Завдання до лабораторної роботи 42
Контрольні питання 42
Лабораторна робота № 4. Компоненти Borland C++ Builder 6 для представлення даних 43
Теоретичні відомості 43
4.1. Компонента StringGrid 43
4.2. Створення гри із використанням базових компонент Borland C++ Builder 6 46
Завдання до лабораторної роботи 51
Контрольні питання 51
Список літератури 52
НАВЧАЛЬНЕ ВИДАННЯ
Візуальне програмування
при обєктно-орієнтованому підході
до виконання лабораторних робіт з дисципліни
“Обєктно-орієнтоване програмування”
для студентів базового напрямку "Програмна інженерія"
Укладачі Коротєєва Тетяна Олександрівна
Тушницький Руслан Богданович
Муха Тарас Орестович
Редактор
Компютерне верстання
Фіксовані комірки
підпис Label
Закладка подій (Events)
Випадаючий список, який показує, для якої компоненти проглядаються події
Подія в списку подій
Випадаючий список з переліком вже написаних обробників подій
Закладка подій (Events)
Випадаючий список, який показує, для якої компоненти проглядаються події
Подія в списку подій
Випадаючий список з переліком вже написаних обробників подій
(при відсутності таких порожній)
Закладки властивостей (Properties) та подій (Events)
в
д
г
е
б
а
Смуга прокрутки
Нефіксовані комірки
таймер
Timer
SrtringGrid
з іменем
sgGameField
Випадаючий список з переліком компонент
на формі
задання рівня гри CSpinEdit
кнопка
Button
підпис Label
поле вводу Edit з іменем
editTime
підпис Label
з іменем
labelAttemps