Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Програмна інженерія

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 24.11.2024

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

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”

Візуальне програмування

при об’єктно-орієнтованому підході

М Е Т О Д И Ч Н І В К А З І В К И

до виконання лабораторних робіт з дисципліни

Об’єктно-орієнтоване програмування

для студентів базового напрямку "Програмна інженерія"

Затверджено

на засіданні кафедри

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

Протокол № ___ від  ______ 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), яку можна викликати через меню ComponentInstall Packages. Дана закладка дозволяє встановити бібліотеки компонент, вказати які саме бібліотеки використовуються, а також опцію компонування проекту із всіма використовуваними бібліотеками (Build with runtime packages).

      

а                                                                      б

Рис. 9. Налаштування компілятора

Рис. 10. Налаштування бібліотек

Важливість останньої опції розглянемо на такому прикладі. Створимо новий віконний проект. Збережемо його у директорії на диску. Нехай дана опція буде увімкненою. Запустимо проект на виконання (меню RunRun, або клавіша F9). Тепер подивимось розмір виконавчого файлу. В залежності від налаштувань, він складатиме приблизно 25 kB. Тепер вимкнемо опцію і ще раз виконаємо програму. Розмір виконавчого файлу збільшився і становить тепер 396 kB. Це пояснюється тим, що у першому випадку застосування зкомпонувалося у виконавчий файл без бібліотек, які використовуються (VCL, тощо). В іншому випадку всі необхідні бібліотеки були додані до виконавчого файлу. Таким чином, якщо є необхідність виконати застосування на комп’ютері де відсутній Borland C++ Builder, необхідно опцію вимкнути.

Зауважимо, що розмір файлу для відлагодження, який створився в процесі компонування в даному прикладі становить 2 Mb. Для раціонального використання місця на диску, його можна видалити.

Завдання для лабораторної роботи

  1.  Ознайомитись із середовищем Borland C++ Builder 6.
  2.  Створити новий проект. Зберегти його двома способами – через комбінації швидких клавіш та через меню.
  3.  Проглянути у вікні інспектора об’єктів властивості форми. Змінити назву форми та її розміри.
  4.  Запустити на виконання застосування.
  5.  Відкрити опції проекту, змінити налаштування на закладках Application, Compiler, Packages. Запустити на виконання застосування.

Контрольні питання

  1.  Пояснити принцип швидкої розробки застосувань.
  2.  На які частини умовно розділяють середовище розробки Borland C++ Builder?
  3.  Що таке проект в С++  Builder?
  4.  Як можна створити проект із користувацькими вікнами (формами)?
  5.  Як можна створити консольний проект і задати мову С/С++?
  6.  Що таке Object Inspector?
  7.  Які є основні файли проекту?
  8.  Що таке файл відлагодження? Чи можна його видаляти?
  9.  В якому файлі міститься головна main функція у віконному проекті?
  10.  В якому файлі міститься головна main функція у консольному проекті?
  11.  Пояснити призначення бібліотек VCL та CLX.
  12.  Вказати назву закладки у налаштуваннях проекту, де задаються форми, які будуть створені автоматично при виконанні застосування.
  13.  Поснити призначення закладки Compiler у налаштуваннях проекту.
  14.  Яким чином можна створити виконавчий файл, що зможе виконатися на комп’ютері на якому не встановлено Borland C++ Builder?

Лабораторна робота № 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, однакові, то вважається, що обмежень на значення немає.

Завдання для лабораторної роботи

  1.  Ознайомитись із палітрою компонент Borland C++ Builder 6.
  2.  Створити віконний проект, додати розглянуті візуальні компоненти.

3.  Реалізувати калькулятор.

Контрольні питання

  1.  Пояснити призначення компоненти Label.
  2.  Пояснити призначення компоненти Edit.
  3.  Чим відрізняюються кнопки Button та BitBtn?
  4.  Пояснити призначення компонент CheckBox і CheckBoxList.
  5.  Які три стани може мати компонента CheckBox?
  6.  Пояснити призначення компоненти CspinEdit.
  7.  Як можна задати мінімальне та максимальне значення для компоненти CspinEdit?
  8.  Що таке подія у візуальному програмуванні?
  9.  Яка основна подія кнопки?
  10.  Як здійснюється доступ в коді до властивостей і методів?
  11.  Пояснити призначення функцій FloatToStr і IntToStr.
  12.  Пояснити призначення властивості Name.
  13.  Яка властивість компоненти задає їй колір та шрифт?
  14.  Як програмно задати розташування компоненти на формі?
  15.  Як програмно приховати/показати компоненту на формі?
  16.  Описати процес написання коду для обробника події.
  17.  Яким чином можна забезпечити для декількох різних компонент виконання одного обробника події?


Лабораторна робота № 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

Основна властивість компоненти  ColorDialogColor. Дана властивість відповідає кольору, який вибрав користувач у діалозі. Приклад використання компоненти:

if (ColorDialog1->Execute())

{

RichEdit1->Color = ColorDialog1->Color;

}

Діалоги друку та встановлення принтера – компоненти PrintDialog і PrinterSetupDialog. Компонента PrintDialog викликає діалогове вікно друку (рис. 37), в якому користувач може вибрати принтер і встановити його властивості, вказати кількість копій і чергування їх друку, друк у файл чи безпосередньо на принтер, вибрати сторінки для друку тощо. Компонента PrintDialog не здійснює друк. Вона лише дозволяє користувачу задати атрибути друку. Сам друк повинен реалізовуватись програмно за допомогою об’єкта Printer або іншим чином. На відміну від розглянутих діалогів, PrintDialog повертає низку властивостей, що характеризують вибрані користувачем налаштування (табл. 2).

Перед викликом діалога бажано визначити кількість сторінок у друкованому тексті, і задати властивості MaxPage і MinPage. У протилежному випадку користувачу буде недоступна опція Сторінки з ... по ... (Pages fromto)(рис. 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. Приєднання компонент до форми та їх вигляд при роботі застосування

Завдання для лабораторної роботи

  1.  Створити віконний проект. Додати головне та контекстне меню, необхідні системні діалоги.
  2.  Реалізувати текстовий редактор і переглядач графічних файлів.

Контрольні питання

  1.  Пояснити чим відрізняються візуальні компоненти від невізуальних.
  2.  Які системні діалоги представлені у Borland C++ Builder 6?
  3.  Яким методом здійснюється виклик системного діалогу?
  4.  Для чого призначена властивість Filter?
  5.  Чи здійснює друк компонента PrintDialog?
  6.  Чи здійснюють пошук та заміну компоненти FindDialog і ReplaceDialog?
  7.  Пояснити призначення компоненти Timer.
  8.  Як запустити/зупинити таймер?
  9.  Продемонструвати використання компонент MainMenu та PopupMenu.
  10.  В якій властивості компонент MainMenu та PopupMenu зберігаються елементи меню?
  11.  Як приєднати головне меню до форми?
  12.  Як приєднати контекстне меню до компоненти?
  13.  Продемонструйте роботу з конструктором меню для компоненти MainMenu.
  14.  Скільки компонент MainMenu та PopupMenu може міститись на формі?


Лабораторна робота № 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» (б)

 

Завдання для лабораторної роботи

  1.  Ознайомитись із компонентою StringGrid.
  2.  Реалізувати гру.

Контрольні питання

  1.  Пояснити призначення компоненти. StringGrid.
  2.  Які властивості компоненти StringGrid відповідають за відображення текста в комірці?
  3.  Якими властивостями компоненти StringGrid можна задати кількість рядків і стовпчиків?
  4.  Якими властивостями компоненти StringGrid можна задати кількість фіксованих рядків і стовпчиків?
  5.  Яка властивість компоненти StringGrid задає можливість редагування комірок?
  6.  Яка подія компоненти StringGrid виникає у момент вибору користувачем комірки?


Список літератури

  1.  А.Я. Архангельский. Программирование в C++ Builder 6. – М.: БИНОМ, 2003, 1152 с.
  2.  А.Я. Архангельский. C++ Builder 6. Справочное пособие. Книга 1. Язык С++. – М.: БИНОМ, 2002, 1152 с.
  3.  А.Я. Архангельский. C++ Builder 6. Справочное пособие. Книга 2. Классы и компоненти. – М.: БИНОМ, 2002, 521 с.
  4.  А.Я. Архангельский. Приемы программирования в C++ Builder 6 и 2006: механизмы Windows, сети. – М.: БИНОМ, 2006, 992 с.
  5.  Джаррод Холингворт, Боб Сворт, Марк Кэшмэн, Поль Густавсон. Borland C++ Builder 6. Руководство разработчика. – М.: Изд. дом «Вильямс», 2004, 976 с.
  6.  Владимир Шамис. Borland C++ Builder 6. Для профессионалов. – М.: Питер, 2005, 800 с.
  7.  М. Теллес. Borland C++ Builder. Библиотека программиста. – М.: Питер, 1998, 512 с.


З М І С Т

Вступ            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




1. тема общественных отношений
2. Доля політичної нації в поліетнічному суспільстві
3. Уральский государственный университет физической культуры кафедра Теории государства и права и констит
4. Устные высказывания и их особенности беседа лекция доклад диспут дискуссия
5. тема управления государственной собственностью Глава 3
6. Общаться с ребенком1
7. Longmn Business English Dictionry BBYY LINGUO The Encyclopedi Britnnic Trdos Google Trnslte отраслевой словарь электро
8. тема Источники уголовнопроцессуального права
9. кОНТРОЛЬНАЯ РАБОТА Дисциплина История Вариант 7 Выполнила Студ
10. Основы горного дел
11. .Протест представление постановление предостережение прокурора в порядке общего надзора Одной из основн
12. 112003 N 141ФЗ от 0607
13. Что такое паевой инвестиционный фонд ПИФ 2
14. Вятский государственный гуманитарный университет ВятГГУ УТВЕРЖДАЮ РекторВ
15. Цифровые системы передачи вар
16. тема России прошла сложный путь развития в рамках различных хозяйственных укладов
17. Реферат студентки 4 курса дневного отделения- Гафеевой Алины Арслановны СанктПетербург
18. Причины конфликтов в современной Африке
19. 5 кг Сушка нет Управление электронное интеллект
20. ИЗУЧЕНИЕ ОСНОВ СПЕКТРОФОТОМЕТРИЧЕСКОГО ОПРЕДЕЛЕНИЯ ПАРАМЕТРОВ ТОНКИХ ПЛЕНОК 7