Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Порядок виконання і методичні вказівки з її виконання






 

3.3.1 Створення додатка. Після відкриття Builder C++ уже є форма, потрібно задати їй підходящі розміри й у вікні редагування властивостей об'єкта змінити стандартне ім'я на своє (fTelephoneBase). Дану процедуру необхідно робити зі всіма об'єктами. Потім слід змінити властивість BorderStyle на bsSingle, тим самим забороняємо зміну розмірів вікна під час виконання додатка. Розкрийте властивість BorderIcons (подвійне клацання лівою кнопкою мишки на хрестику поруч з написом) і в розкриваючому підменю змініть властивість biMaximize (забороняємо розгортання на весь екран). Перейдіть на закладку Event (клацання лівою клавішею на прямокутнику з даним написом, що знаходиться над властивостями об'єкта, але під полем вибору об'єкта) робіть подвійне клацання в області напроти напису OnCreate, створюючи тим самим оброблювач події “Створення форми”). Після цього Ви повинні опинитися у вікні редагування коду у функції void __fastcall TfTelephoneBase:: FormCreate(TObject *Sender), де необхідно ввести код обробки даної події (прим. зараз у вікні редагування об'єктів Ви повинні знаходитися на закладці подій, якщо знадобиться редагувати властивості об'єкта, клацніть лівою кнопкою мишки на прямокутнику з написом Properties).

 

3.3.2 Формування набору елементів форми. У запропонованому, як приклад, варіанті роботи використовуватимуться такі елементи форми:

 

- Меню MainMenu (1) - Напис Label (2) - Поле введення тексту Edit (3) - Поле виведення тексту Memo (4) - Кнопка Button (5) - Комбінований список ComboBox (7) - Елемент GroupBox (6) - У вкладці панелі інструментів Additional (А) елемент Bevel (8) - У вкладці Dialogs (B) діалоги відкриття і збереження OpenDialog (9) і SaveDialog (10)

 

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

1. Розмістити на формі сім кнопок Button(5). І відразу задайте кожну з них властивості Name і Caption. Ці властивості знаходяться на панелі Object Inspector, у вкладці Properties. Один раз клацнувши мишкою на одну з кнопок, можна помітити, що у вікні Object Inspector був автоматично обраний відповідний об'єкт і запропонований для зміни властивість Caption. Змініть його значення на потрібну назву кнопки. Першу кнопку найкраще назвати «Додати». Трохи нижче в списку, серед інших властивостей, знаходиться властивість Name. Це ім'я, що використовується для звертання до об'єкта. Змініть значення властивості Name з Button1 на btnAdd. Аналогічні зміни слід зробити для кожної з кнопок, що залишилися, відповідно:

Button2: Caption – Видалити, Name – btnDelete;

Button3: Caption – Обновити, Name – btnRefresh;

Button4: Caption – Відкрити, Name – btnOpen;

Button5: Caption – Зберегти, Name – btnSave;

Button6: Caption – Звіт, Name – btnReport;

Button7: Caption – Вихід, Name – btnExit.

Створити елемент GroupBox(7) і розтягніть його межі приблизно на чверть форми. Цей об'єкт служить для угруповання об'єктів різного призначення на формі. Елемент GroupBox також має властивості Caption і Name. Задайте цим властивостям значення Користувач і gbUser відповідно.

3. Наступним кроком буде приміщення 3-х елементів Label(2) і 3-х елементів Edit(3) в область елемента GroupBox. Їх слід розташувати так, як показано на рис. 3.1. Кожному напису Label привласніть Caption Прізвище, Телефон і Час відповідно, а також, щоб не відступати від стилю привласніть імена Name: lName, lTelephone, lTime. В елементів Edit відсутня властивість Caption, однак вони мають іншу важливу для нас властивість – Text. Значення властивості Text краще залишити порожнім. Потім задайте кожному з Edit ім'я: eName, eTelephone і eTime відповідно. Необхідно пам'ятати, що в мові С++ між великими і малими літерами є різниця, тому під час написання програм слід стежити за регістром символів в імені об'єкта.

 

Рисунок 3.1 – Форма заповнювання даних про абонента

 

4. Створіть на формі елемент ComboBox (6), він призначений для створення списку, плюс можливість ручного вибору імені, що входить у цей список. Значення властивості Name цього елемента слід замінити на cbUsers, а значення властивості Text – залишити порожнім.

5. У вкладці панелі інструментів Additional(А) виберіть елемент Bevel(8) і встановіть його на форму так, щоб він зайняв половину форми, що залишилася. Задайте йому Name: bReport. Всередині елемента Bevel розташуєте Label(2) з Caption приблизно такого змісту: «Інформація про користувачів, що знаходяться в базі даних:» і Name: lReport. Під написом створіть елемент Memo(4) з Name: mReport і новою властивістю ScrollBars, значення якого слід задати ssVertical. Ця властивість відповідає за відображення вертикальної смуги прокручування у текстовому вікні.

6. У вільному місці форми створіть елементи OpenDialog(9) і SaveDialog(10), за допомогою них здійснюватиметься вибір імені файла, у якому вироблятиметься відкриття або запис. Ці об'єкти не відображатимуться на формі в момент роботи програми, саме тому їхні координати не мають значення. Задайте елементові OpenDialog Name: OpenDialog, а SaveDialog значення імені SaveDialog. Обом цим елементам задайте додаткові значення властивостей, що відповідають за відкриття і збереження файлів з визначеним розширенням. Значенням властивості DefaultExt необхідно привласнити tbf, а значенню властивостей Filter даний текст: «Файл телефонної бази (*.tbf)|*.tbf| будь-який файл (*.*)|*.*», без лапок.

7. Створіть елемент меню MainMenu(1). Його розташування, аналогічно діалогам, не має значення. Привласнимо йому ім'я mnuMain. Подвійним клацанням мишки на іконку об'єкта відкрийте редактор меню. У вікні, що відкрилося, привласніть ім'я mnuFile і Caption - «Файл», створеному за замовчуванням першому елементові меню. Після одиночного клацання на розділі, що вийшов, меню привласніть вхідним в розділ елементам такі властивості: імена(Name): mnuFOpen, mnuFSave, mnuFExit і заголовки(Caption): Відкрити, Зберегти, Вихід відповідно. Створіть другий розділ з ім'ям mnuEdit і заголовком «Виправлення». Привласніть вхідним в цей розділ елементам такі властивості: імена(Name): mnuENew, mnuEAdd, mnuERefresh, mnuEDelete, mnuEReport і заголовки(Caption): Створити, Додати, Обновити, Видалити, Звіт відповідно.

 

3.3.3 Опис подій елементів форми. Описи подій елементів форми задаються мовою С++, шляхом подвійного клацання на описуваний об'єкт або вибору у вкладці Events вікна Object Inspector потрібної події і введення, у вікні, що з'явилося, між фігурними дужками тексту програми. Слід зазначити, що у вікні, що з'явилося, уже знаходиться текст автоматично створений Вuіldеr'ом для роботи взаємодії модулів проекту. Цей текст краще не змінювати.

Наприклад, подія з ім'ям btnAddClick, що описує результат натискання на кнопку Додати (btnAdd) із самого початку має такий вигляд:

 

void __fastcall TfTelephoneBase:: btnAddClick (TObject *Sender)

{

 

}

 

Сам текст програми міститьсятільки між фігурними дужками.

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

1. Для опису оброблювача події OnClick кнопки «Додати» клацнути двічі на ній і у вікні, що відкрилося, між фігурними дужками помістите наступний текст (рядки-коментарі пояснюють призначення відповідних рядків програми і для введення необов'язкові):

 

//пошук вільної адреси для створення нового користувача

int i;

for(i = 0; (i < Max - 1)& & (Data[i]! = NULL); i++);

if(Data[і]! = NULL)

{

Application-> MessageBox(" Не вистачає пам'яті для виконання дії",

" Помилка! ",

MB_OK|MB_ICONERROR|MB_APPLMODAL);

return;

};

iCurrent = і;

for(і = 0; (і < Max - 1); і++)//пошук користувача по імені

if (Data[i]! = NULL)

if(eName-> Text == Data[i]-> Name) break;

if (Data[i]! = NULL)

if(Data[i]-> Name == eName-> Text)

{

Application-> MessageBox(" Дублювання імені абонента. Змініть ім'я абонента.",

" Дублювання імені! ",

MB_OK|MB_ICONERROR|MB_APPLMODAL);

eName-> Text = " ";

eName-> SetFocus();

return;

};

//перед заповненням нового запису перевіряємо чи всі поля заповнені

if(eName-> Text == " ")

{

Application-> MessageBox(" Необхідно ввести ім'я!!! ",

" Не введене ім'я! ",

MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

eName-> SetFocus();

return;

};

if(eTelephone-> Text == " ")

{

Application-> MessageBox(" Необхідно ввести телефон!!! ",

" Не введений телефон! ",

MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

eTelephone-> SetFocus();

return;

};

if(eTime-> Text == " ")

{

Application-> MessageBox(" Необхідно ввести час розмови!!! ",

" Не введений час! ",

MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

eTime-> SetFocus();

return;

};

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

btnDelete-> Enabled = true;

mnuEDelete-> Enabled = true;

btnSave-> Enabled = true;

mnuFSave-> Enabled = true;

cbUsers-> Enabled = true;

btnReport-> Enabled = true;

mnuEReport-> Enabled = true;

mReport-> Visible = false;

bIsEdit = false;

mnuERefresh-> Enabled = false;

btnRefresh-> Enabled = false;

//заповнюємо властивості нового екземпляра об'єкта

Data[i] = new User;

iCurrent = i;

Data[iCurrent]-> Name = eName-> Text;

Data[iCurrent]-> SetTelephone(eTelephone-> Text);

Data[iCurrent]-> SetTime(eTime-> Text);

//обновляємо список користувачів

RebindUsers();

 

2. Щоб вилучити зайвий запис, задайте ОnClick кнопки «Вилучити»:

 

if (bIsEdit)//якщо користувач редагувався, вилучаємо його

{

delete Data[iCurrent];

Data[iCurrent] = NULL;

RebindUsers(); //список користувачів змінився, перебудовуємо його

};

 

int i;

for(і = 0; (і < Max - 1)& & (Data[і] == NULL); і++); //перевірка вилучена

// останній користувач

if (Data[і] == NULL)//якщо останній, то забороняємо редагування

{

btnDelete-> Enabled = false;

mnuEDelete-> Enabled = false;

btnSave-> Enabled = false;

mnuFSave-> Enabled = false;

btnReport-> Enabled = false;

mnuEReport-> Enabled = false;

cbUsers-> Enabled = false;

}

else

{

btnSave-> Enabled = true;

mnuFSave-> Enabled = true; //дозволяємо збереження

};

mnuENewClick(Sender); //виклик для очищення полів редагування

mReport-> Visible = false; //рапорт змінився, просто ховаємо його

btnDelete-> Enabled = false; //забороняємо редагування

mnuEDelete-> Enabled = false;

bIsEdit = false; //очищаємо прапорець редагування

mnuERefresh-> Enabled = false;

btnRefresh-> Enabled = false;

 

3. Для читання звітів з файла. Задайте ОnClick кнопки «Відкрити»:

 

bool Error = false;

OpenDialog-> Title = " Відкрити..."; //присвоюємо заголовок діалогові вибору файла

bool Execute = OpenDialog-> Execute();

if(Execute)

{

//створюємо клас роботи з файлом

File = new FileDialog(OpenDialog-> FileName, FD_OPEN);

Error =! File-> ReadFile(Data, Max); //збереження результатів роботи

delete File; //вилучення екземпляра

File = NULL;

};

 

if(! Error)//перевірка на помилку під час читання файла

{//помилки небуло

if(! Execute) return; //користувач не вибрав файл

//відкриття відбулося нармально, дозволяємо редагування

btnDelete-> Enabled = true;

mnuEDelete-> Enabled = true;

btnSave-> Enabled = true;

mnuFSave-> Enabled = true;

cbUsers-> Enabled = true;

btnReport-> Enabled = true;

mnuEReport-> Enabled = true;

mReport-> Visible = false;

bIsEdit = false;

mnuERefresh-> Enabled = false;

btnRefresh-> Enabled = false;

eName-> Text = " ";

eTelephone-> Text = " ";

eTime-> Text = " ";

RebindUsers();

}

else

{//обробка помилки під час читання файла

Application-> MessageBox(" Помилка під час відкриття файла!!! ",

" Помилка", MB_OK|MB_ICONERROR|MB_APPLMODAL);

};

 

4. Для збереження звітів у файл. Задайте ОnClick кнопки «Зберегти»:

 

bool Error = false;

SaveDialog-> Title = " Зберегти..."; //присвоюємо заоловок діалогові вибору файла

bool Execute = SaveDialog-> Execute();

if(Execute)//якщо обрано файл

{

//створюємо клас роботи з файлом

File = new FileDialog(SaveDialog-> FileName, FD_SAVE);

//перевірка помилки збереження

Error =! File-> WriteFile(Data, Max);

delete File; //вилучаємо екземпляр роботи з файлом

File = NULL;

};

if (! Error)

{//помилки під час запису у файл небуло

if(! Execute) return; //користувач не вибрав файл

btnSave-> Enabled = false; //файл збережений нормально

mnuFSave-> Enabled = false;

}

else

{//обробка помилки запису у файл

Application-> MessageBox(" Помилка під час відкриття файла!!! ",

" Помилка", MB_OK|MB_ICONERROR|MB_APPLMODAL);

};

 

5. Задайте ОnClick кнопки «Звіт»:

 

//створення звіту про користувачів даних, що знаходяться в базі

AnsiString tmp;

mReport-> Lines-> Clear(); //очищення

for(int i = 0; i < Max; i++)

if(Data[i]! = NULL)

{

lReport-> Visible = true;

mReport-> Visible = true; //робимо видимим поле звіту

 

tmp = " Прізвище: " + Data[і]-> Name; //виводимо складового списку

mReport-> Lines-> Add(tmp);

tmp = " Телефон: " + Data[і]-> GetTelephone();

mReport-> Lines-> Add(tmp);

tmp = " Тип дзвоника: " + Data[і]-> GetType();

mReport-> Lines-> Add(tmp);

tmp = " Час розмови: " + Data[і]-> GetTime();

mReport-> Lines-> Add(tmp);

tmp = " До оплати: " + AnsiString(Data[і]-> GetAccount());

mReport-> Lines-> Add(tmp);

mReport-> Lines-> Add(" ");

};

 

6. Задайте подію OnClick кнопки «Вихід»:

 

fTelephoneBase-> Close(); //закриваємо додаток(головну форму)

 

7. Оброблювачем події OnClick кнопки «Обновити»

 

if(bIsEdit)

{

//обновляє вміст зміненого елемента списку

Data[iCurrent]-> Name = eName-> Text;

Data[iCurrent]-> SetTelephone(eTelephone-> Text);

Data[iCurrent]-> SetTime(eTime-> Text);

RebindUsers();

cbUsers-> Text = eName-> Text;

 

btnSave-> Enabled = true;

mnuFSave-> Enabled = true;

};

 

8. Для всіх пунктів меню задайте обробники події OnClick відповідних кнопок форми. Наприклад, для пункту меню «Відкрити» використовуйте уже введений оброблювач цієї події кнопки «Відкрити», тобто в правому полі, напроти події OnClick пункту меню, виберете зі списку існуючих імен оброблювачів ім'я btnOpenClick.

 

9. Опис оброблювача події OnClick пункту меню «Створити»:

 

eName-> Text = " "; //очищення полів уведення

eTelephone-> Text = " ";

eTime-> Text = " ";

 

bIsEdit = false; //скидання прапора ребактирования

mnuERefresh-> Enabled = false;

btnRefresh-> Enabled = false;

 

eName-> SetFocus(); //фокус на поле введення імені

 

10. Для вибору прізвища користувача, чий звіт буде виведений, опишіть подію Change елемента cbUsers (ComboBox):

 

int і;

for(і = 0; (і < Max - 1); і++)//пошук користувача по імені

if (Data[i]! = NULL)

if(cbUsers-> Text == Data[i]-> Name) break;

//підстановка значень полів

eName-> Text = Data[i]-> Name;

eTelephone-> Text = Data[i]-> GetTelephone();

eTime-> Text = Data[i]-> GetTime();

iCurrent = і;

bIsEdit = true; //виставляємо прапорець редагування

mnuERefresh-> Enabled = true;

btnRefresh-> Enabled = true;

btnDelete-> Enabled = true; //дозволяємо видаляти

mnuEDelete-> Enabled = true;

 

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

 

Для внесення в список нового користувача, необхідно внести такі рядки:

 

void TfTelephoneBase:: RebindUsers()

{

//знищуємо старий список

cbUsers-> Clear();

//проходимо в циклі всі осередки

for(int i = 0; i < Max; i++)

if(Data[i]! = NULL)

{

//даний користувач створений

cbUsers-> Items-> Add(Data[i]-> Name);

}

}

11. Задайте конструктор, що звільнює пам'ять:

 

__fastcall TfTelephoneBase:: TfTelephoneBase(TComponent* Owner)

: TForm(Owner)

{

//обнуління масиву адрес

for (int i = 0; i < Max; i++)Data[i] = NULL;

iCurrent = 0;

}

 

12. Задайте деструктор, що звільнює пам'ять:

 

__fastcall TfTelephoneBase:: ~TfTelephoneBase()

{

for(int i = 0; i < Max; i++)

if(Data[i]! = NULL) delete Data[i];

}

13. Створення модуля User

 

Для створення модуля User необхідно у вже створеному проекті вибрати пункт головного меню File, а в ньому пункт New…(рис. 3.2).

У вікні, що з'явилося, New Items виберіть (подвійне клацання лівою кнопкою) іконку з підписом Unit.

Після цього в проекті з'явиться модуль з назвою типу Unit*.cpp (замість * стоятиме номер модуля), для перейменування його в User необхідно вибрати пункт Save As…у меню File. При цьому активним має бути тільки що створений модуль, а зберігати потрібно в папку, де зберігається весь проект. Рекомендується зберігати проект в окремій папці.

 

 

Рисунок 3.2 – Фрагмент головного меню File

 

Після цього необхідно відкрити заголовний файл натисканням правої кнопки на написі User.cpp, що знаходиться у вікні редагування тексту ледве вище самого тексту. При цьому необхідно переконатися, що прямокутник з даним написом, як би опуклий у порівнянні з іншими. У меню, що з’явилося виберіть пункт Open Source/Header File (рис. 3.3). У результаті має з'явитися файл User.h, після проробленого слід зберегти весь проект (Пункт Save All... у меню File).

 

 

 

Рисунок 3.3 – Фрагмент головного меню User.cpp

 

Файл User.h служить для визначення класу User. Введіть у файл User.h нижчеподані рядки, їх необхідно вставляти перед рядком #endif. Під час введення тексту коментарі допускається змінювати або не вводити.

 

const short ID_NONE = 0, //тип дзвоника невизначений

ID_CITY = 1, //міжміський

ID_LONG_DISTANCE = 2, //міський

ID_IN_ZONE = 3, //внутрішньозоновий

ID_NATIONAL = 4; //міжнародний

const double TARIF[] = {0.0, 0.024, 0.06, 0.6, 6.0}; //масив тарифів

const AnsiString CALL_TYPE[] = {" NONE", " CITY", //масив рядків

" LONG_DISTANCE", //для типу дзвоника

" ZONE",

" NATIONAL" };

//визначення класу

class User

{

private:

AnsiString asTelephone; //поле збереження телефону

unsigned iTime; //поле часу розмови

short sType; //поле типу розмови

void InitType(); //процедура визначення типу

protected:

public:

AnsiString Name;

User() {asTelephone = " "; //конструктор класу

iTime = 0;

sType = ID_NONE;

Name = " "; };

~User() {};

//деструктор, що звільнює пам'ять

void SetTelephone(AnsiString Telephone);

AnsiString GetTelephone() const; // функція виведення телефону

void SetTime (AnsiString Time); //установка номера

AnsiString GetTime() const; //видача номера

AnsiString GetType() const; //видача типу

double GetAccount() const; //обчислення і повернення вартості розмови

};

 

Файл User.cpp. Всі основні операції з інформацією про абонента проводитимуться цією частиною програми.

Створіть файл User.cpp і помістіть в нього наступні рядки.

 

#include < math.h>

//процедура установки телефону

void User:: SetTelephone(AnsiString Telephone)

{

if (Telephone! = " ") this-> asTelephone = Telephone;

InitType(); //після установки телефону відразу визначаємо тип дзвоника

};

//функція повернення телефону

AnsiString User:: GetTelephone() const

{

return this-> asTelephone;

};

//установка часу розмови

void User:: SetTime (AnsiString Time)

{

if (Time! = " ") this-> iTime = Time.ToInt();

};

//повернення часу розмови

AnsiString User:: GetTime() const

{

AnsiString tmp(iTime);

return tmp;

};

//повернення типу дзвоника

AnsiString User:: GetType() const

{

return CALL_TYPE[this-> sType];

};

//обчислення і повернення вартості розмови

double User:: GetAccount() const

{

double tmp = ceil(iTime * TARIF[sType] * 100) / 100;

return tmp;

};

//схована процедура визначення типу

void User:: InitType()

{

//аналіз внутрішньоміського дзвоника

if (this-> asTelephone[1]! = '8')

{

sType = ID_CITY;

return;

};

int і;

//дзвоник не міський, шукаємо другу цифру

for (і = 2; (asTelephone[і] == '-')& & (і < = asTelephone.Length()); і++);

//аналіз другої цифри

switch (asTelephone[i])

{

case '2': sType = ID_IN_ZONE;

break;

case '0': sType = ID_NATIONAL;

break;

default: sType = ID_LONG_DISTANCE;

};

};

 

Модуль FileDialog. Для організації читання і запису даних у файл використовується модуль FileDialog.cpp і заголовний файл FileDialog.h, що повідомляє клас FileDialog. Заголовний файл і файл.cpp модуля створюються аналогічно модулеві User. Нижче наведено тексти програм, які необхідно вставити у створений файл FileDialog.h:

 

#include " User.h"

//оголошення констант узгодження з класом TFileStream

#define FD_OPEN fmOpenReadWrite|fmShareDenyWrite

#define FD_SAVE fmOpenReadWrite|fmShareDenyWrite|fmCreate

class FileDialog: public TFileStream

{

private:

char *cBuffer; //буфер для збереження лічених даних

unsigned iByteCount; //лічильник байт у файлі

unsigned iUserCount; //лічильник записів у файлі

protected:

//процедура знищення виділеної пам'яті

inline void DestroyTemp(User *Data[], const unsigned Len);

public:

//конструктор класу

__fastcall FileDialog(const AnsiString FileName, const Word Mode);

//деструктор класу

__fastcall ~FileDialog();

//функція читання записів з файла

virtual bool ReadFile(User *Data[], const unsigned Len);

//функція запису у файл

virtual bool WriteFile(User *Data[], const unsigned Len);

void Reset();

};

//--------------------------------------------------------------

#endif

 

 

Файл FileDialog.cpp. Ці рядки необхідно вставити у файл FileDialog.cpp (коментарі можна не вводити):

 

#include < string.h>

#include < mem.h>

 

//конструктор класу

__fastcall FileDialog:: FileDialog(const AnsiString FileName, const Word Mode)

: TFileStream(FileName, Mode)

{

//ініціація внутрішніх перемінних

cBuffer = NULL;

iByteCount = 0;

iUserCount = 0;

};

__fastcall FileDialog:: ~FileDialog()

{

//очищення виділеної пам'яті

if(cBuffer! = NULL) delete cBuffer;

};

bool FileDialog:: ReadFile(User *Data[], const unsigned Len)

{

char *tmp, *pos1, *pos2, ch[20];

unsigned і, j, cx;

//зчитування заголовка файла

tmp = new char[4];

if (TFileStream:: Read(tmp, 4)! = 4) return false;

if (strncmp(tmp, " tbf", 3)! = 0) return false;

//зчитування довжини в байтах

if(Read(& iByteCount, 4)! = 4) return false;

delete tmp;

tmp = new char;

if(Read(tmp, 1)! = 1) return false;

if(strncmp(tmp, " ", 1)! = 0) return false;

//зчитування кількості записів

if(Read(& iUserCount, 4)! = 4) return false;

iUserCount = (Len < iUserCount)? Len: iUserCount;

if(Read(tmp, 1)! = 1) return false;

if(strncmp(tmp, " ", 1)! = 0) return false;

//створення буфера довгої рівної недочитаної частини файла

cBuffer = new char[iByteCount];

//зчитування залишку файла в буфер

if(Read(cBuffer, iByteCount)! = iByteCount)

{

DestroyTemp(Data, Len);

return false;

};

//ініціалізація тимчасових покажчиків

pos1 = cBuffer; //початок поля в записі

pos2 = NULL; //кінець поля в записі

cx = 0;

for (i = 0; i < iUserCount; i++)

{

//пошук вільного запису в масиві Data

for(; (cx < Len - 1)& & (Data[i]! = NULL); cx++);

if(Data[cx]! = NULL)

{

DestroyTemp(Data, Len);

return false;

};

Data[і] = new User;

//зчитування імені

pos2 = pos1 + 1;

for(j = 0; (j < 20)& & (*pos2! = '\0'); j++, pos2++);

if ((j == 20)& & (*pos2! = 0))

{

DestroyTemp(Data, Len);

return false;

};

strncpy(ch, pos1, pos2 - pos1 + 1);

Data[і]-> Name = ch; //зберігаємо ім'я

pos1 = pos2 + 1; //покажчик на наступне поле

pos2 += 2; //покажчик кінця поля на другий символ поля

//знаходимо кінець поля і запам'ятовуємо його в pos2

for(j = 0; (j < 20)& & (*pos2! = '\0'); j++, pos2++);

if ((j == 20)& & (*pos2! = 0))

{

DestroyTemp(Data, Len);

return false;

};

strncpy(ch, pos1, pos2 - pos1 + 1);

Data[і]-> SetTelephone(ch); //збереження телефону

pos1 = pos2 + 1;

pos2 += 2;

for(j = 0; (j < 20)& & (*pos2! = '\0'); j++, pos2++);

if ((j == 20)& & (*pos2! = 0))

{

DestroyTemp(Data, Len);

return false;

};

strncpy(ch, pos1, pos2 - pos1 + 1);

Data[і]-> SetTime(ch); //збереження часу

pos1 = pos2 + 1;

pos2 += 2;

cx++;

};

if(cBuffer! = NULL) delete[] cBuffer;

return true;

};

bool FileDialog:: WriteFile(User *Data[], const unsigned Len)

{

unsigned i, j;

char *pos1;

iByteCount = 0;

iUserCount = 0;

//чикл підрахунку кількості записів і їх загальної довжини

for(i = 0; i < Len; i++)

{

if (Data[i] == NULL) continue;

iUserCount++;

//одиниця додається для нульового символу

iByteCount += Data[i]-> Name.Length() + 1;

iByteCount += Data[i]-> GetTelephone().Length() + 1;

iByteCount += Data[i]-> GetTime().Length() + 1;

};

//запит пам'яті в системи для тимчасового формування структури записів

//14 довина заголовка файла

cBuffer = new char[iByteCount + 14];

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

pos1 = cBuffer;

memcpy(pos1, " tbf\0", 4);

pos1 += 4;

memcpy(pos1, & iByteCount, 4); //запис довгі в байтах

 

pos1 += 4;

memcpy(pos1, " \0", 1); //запис роздільника

pos1 += 1;

memcpy(pos1, & iUserCount, 4); //запис кількості користувачів

pos1 += 4;

memcpy(pos1, " \0", 1); //запис роздільника

pos1 += 1;

//заголовок файла сформований, далі розміщуватимуться самі записи

//цикл запису користувачів у буфер

for(i = 0; i < Len; i++)

{

if(Data[i] == NULL) continue;

memcpy(pos1, Data[i]-> Name.c_str(), Data[i]-> Name.Length() + 1);

pos1 += Data[i]-> Name.Length() + 1;

memcpy(pos1, Data[i]-> GetTelephone().c_str()

, Data[i]-> GetTelephone().Length() + 1);

pos1 += Data[i]-> GetTelephone().Length() + 1;

memcpy(pos1, Data[i]-> GetTime().c_str()

, Data[i]-> GetTime().Length() + 1);

pos1 += Data[i]-> GetTime().Length() + 1;

};

Reset(); //скидання покажчика у файлі на початок

//запис сформованого буфера в пам'ять

Write(cBuffer, iByteCount + 14);

return true;

};

void FileDialog:: Reset()

{

//установлення покажчика у файлі на початок

Seek(0, soFromBeginning);

};

inline void FileDialog:: DestroyTemp(User *Data[], const unsigned Len)

{

//звільнення виділеної пам'яті

if(cBuffer! = NULL) delete[] cBuffer;

for(unsigned i = 0; i < Len; i++) if(Data[i]! = NULL) delete Data[i];

};

14. Компіляція і виконання проекту.

Зберігаючи проект останній раз, необхідно порівняти структуру файлів проекту, показану в Project Manager, зі структурою на рис. 3.4. Усі зображені файли мають бути присутніми у Project Manager, інакше слід перетворити відсутні модулі.

Далі необхідно запустити проект на компіляцію і виконання (іконка Run або клавіша F9).

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

 

Рисунок 3.4 – Фрагмент вікна Project Manager

 

Під час збереження файлів проекту, небажано зберігати їх у папках, що вже містили інші проекти або програмні модулі Builder. Слід також зазначити, що програма була написана на Borland C++ Builder 4 Pro, і на більш ранніх версіях цього пакета працювати не буде! Програма пройшла тестування на сумісність з Builder v.5.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.