Первая страница
Наша команда
Контакты
О нас

    Головна сторінка



Та програмування

Та програмування




Сторінка10/11
Дата конвертації10.03.2017
Розмір2.35 Mb.
1   2   3   4   5   6   7   8   9   10   11

Структуру файлу Pokupatel.dat мовою С можна описати у вигляді:
struct Pokupatel

{

char name[15];



char posada[10];

char phone[15];

}

База даних замовлень у вигляді файлу Cmplbase.dat містить у собі номер замовлення, код товару, дату замовлення, фірму-клієнта, ім'я покупця, назву товару, ціну одиниці товару, кількість купленого товару, загальну ціну (суму товару), оплату клієнта. Структура файлу Cmplbase.dat наведена в таблиці 7.6.

Таблиця 7.6 – Структура файлу Cmplbase.dat


№ поля

Зміст поля


Найменування (на С) поля

Розмір

Тип поля

1

Номер замовлення

znomer

3

char[3]

2

Код товару

code

3

char[3]

3

Дата замовлення

date

10

char[10]

4

Фірма (клієнт)

zfirma

10

char[10]

5

Ім'я покупця

FIO

15

char[15]

6

Назва товару

tovar

15

char[15]

7

Ціна за 1 шт.

Price

5

char[5]

8

Кількість купленого

number

5

char[5]

9

Ціна загальна

allprice

5

char[5]

10

Оплата клієнта

Payment

5

char[5]

11

Заборгованість

borg

5

char[5]

Структуру файлу Cmplbase.dat мовою С можна описати у вигляді:


struct Final

{

char znomer[3];



char code[3];

char date[10];

char zfirma[10];

char FIO[15];

char tovar [15];

char Price[5] ;

char number[5];

char allprice[5];

char Payment[5];

char borg[5];

}
Для роботи з базами даних насамперед необхідно розробити функції, що виконують такі операції:


  • створення файлу задля збереження інформації;

  • запис даних в файл;

  • зчитування даних з файлу;

  • видалення даних з файлу.

Всі розглянуті вище файли бази даних відрізняються лише структурами записів, тому для прикладу розглянемо лише структуру запису файлу товарів Prodbase.dat.
struct Product

{

char code[4]; // код товару



char tovar[15]; // назва товару

char producer[15]; //фірма-виробник

char discription[15]; // характеристика товару

char price[6]; // вартість товару

char number[6]; // кількість товару на складі

char notes[9]; // примітка

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

Функція int dbf_exists(char *filename) – призначена для перевірки існування файлу.

Існува́ння (від екзистенція) - центральне поняття екзистенціалізму, унікальна особистісна сутність людини, що втілює в собі духовну, психоемоційну неповторність особи.
Якщо файл не існує (тобто файловий потік NULL), то функція повертає значення 0, в іншому випадку повертає значення 1.

Код даної функції наведений нижче:
int dbf_exists( char *filename )

{

FILE *instream=fopen(filename,"rb");



// створення файлового потоку

//*instream для роботи з файлом

// filename, що знаходиться на дискові

if (instream==NULL)

return 0;

else


{

fclose(instream);

return 1;

}

}


Функція int dbf_records(char *fname, Product *prod) –призначена для підрахунку кількості записів структурного типу Product у файлі.

char *fname – назва файлу

Product *prod – тип структури
Код даної функції має такий вигляд:
int dbf_records(char *fname, Product *prod)

{

FILE *instream=fopen(fname,"rb");



if (instream==NULL)

return 0;

else

{

fseek(instream,0L,SEEK_END);//встановлення вказівника в кінець файлу



int flen=ftell(instream);// визначення кількості байтів в частині файлу від його початку до вказівника

fclose(instream);



return flen/sizeof(*prod);// повертаємо число – кількість записів

}

}


Функція void dbf_write_struct(char *filename,Product *prod) – призначена для запису структури типу Product у файл.
Код даної функції має такий вигляд:
void dbf_write_struct(char *filename,Product *prod)

{

FILE *istream=fopen(filename,"ab");



fseek(istream,0L,SEEK_END);//встановлюємо вказівник в кінець файлу

fwrite(prod,sizeof(Product),1,istream);//записуємо з джерела prod розміром Product 1-у порцію у файл

fclose(istream);

}
Функція void dbf_rewrite_struct(char *filename,Product *prod,int record) – призначена для перезапису структури за заданим номером record типу Product у файлі.

Код даної функції має такий вигляд:
void dbf_rewrite_struct(char *filename,Product *prod,int record)

{

FILE *istream=fopen(filename,"r b");



fseek(istream,record*sizeof(Product),SEEK_SET);

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

fwrite(prod,sizeof(Product),1,istream);

fclose(istream);

}
Функція void dbf_delete_record(char *filename, int record) – призначена для видалення запису за заданим номером record з файлу.

Код даної функції має такий вигляд:


void dbf_delete_record(char *filename, int record)

{

FILE *instream = fopen(filename,"rb");



FILE *onstream = fopen(temp_filename_s, "wb");

Product prod;

//int count=-1;

fseek(instream,0L,SEEK_END);//встановлюємо вказівник в кінець файлу

int flen = ftell(instream);//знаходимо розмір файлу в байтах

fseek(instream,0L,SEEK_SET);//встановлюємо вказівник на початок файлу
for(int i=0;i<(flen/sizeof(Product));i )

{

memset(&prod,0,sizeof(Product));



fread(&prod,sizeof(Product),1,instream);//зчитуємо з файлового потоку

// instream в prod одну порцію даних розміром sizeof(Product)

if (i != record)

fwrite(&prod,sizeof(Product),1,onstream);

}

fclose(instream);



fclose(onstream);

unlink(filename);// перевідкриття файлу

dbf_rename(temp_filename_s,filename);//перейменування файлу

}
Функція void dbf_readrecord(char *fname, int record, Product *outdata) призначена для зчитування запису за заданим номером record з файлу в структуру типу Product.
Код даної функції має такий вигляд:

void dbf_readrecord(char *fname, int record, Product *outdata)

{

FILE *istream = fopen(fname,"rb");



fseek(istream,record*sizeof(Product),SEEK_SET);

read(outdata,sizeof(Product),1,istream); // зчитування з файлового потоку istream в комірку пам’яті outdata даних розміром sizeof(Product) одноразово

fclose(istream);

}
Функція int dbf_search(char *fname, int field,char *keyword) призначена для пошуку в файлі необхідних записів за заданим ключовим словом і за заданим полем. Тобто дана функція зчитує всі записи з файлу, шо знаходяться за даними критеріями (поле структури field, ключове слово keyword) і записує всі знайдені записи (структури) в тимчасовий файл temp_filename_s.

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

Код даної функції має такий вигляд:
int dbf_search(char *fname, int field,char *keyword)

{

FILE *instream = fopen(fname ,"rb");



FILE *tmpstream = fopen(temp_filename_s,"wb");

Product prod;

char *pr, *num;

//обнуляємо структуру prod

memset(&prod,0,sizeof(Product));

//встановлюємо вказівник в кінець

//файлу, щоб визначити розмір файлу за допомогою ftell(instream)

fseek(instream, 0L, SEEK_END);

//визначаємо кількість записів

int flen = ftell(instream)/sizeof(Product);

fseek(instream, 0L, SEEK_SET);

//змінюємо всі великі символи рядка на малі

strlwr(keyword); for (int i = 0, count = 0; i < flen; i )

{

fread(&prod,sizeof(Product),1,instream);



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

//з усіма властивостями структури

switch (field)

{

case 1:



//перевірка рівності двох рядків - prod.code і keyword

if (strstr(strlwr(prod.code),keyword) != NULL)

{

//запис в тимчасовий файл знайденого поля



fwrite(&prod,sizeof(Product),1,tmpstream);

count ;


}

break;


case 2:

if (strstr(strlwr(prod.tovar),keyword) != NULL) {

//запис в тимчасовий файл знайденого поля

fwrite(&prod,sizeof(Product),1,tmpstream);

count ;

}

break;



case 3:

if (strstr(strlwr(prod.producer),keyword) != NULL)

{

//запис в тимчасовий файл знайденого поля



fwrite(&prod,sizeof(Product),1,tmpstream);

count ;


}

break;


case 4:

if (strstr(strlwr(prod.discription),keyword) != NULL)

{

//запис в тимчасовий файл знайденого поля



fwrite(&prod,sizeof(Product),1,tmpstream);

count ;


}

break;


case 5:

if (strstr(strlwr(prod.price),keyword) != NULL)

{

//запис в тимчасовий файл знайденого поля



fwrite(&prod,sizeof(Product),1,tmpstream);

count ;


}

break;


case 6:

if (strstr(strlwr(prod.number),keyword) != NULL)

{

//запис в тимчасовий файл знайденого поля



fwrite(&prod,sizeof(Product),1,tmpstream);

count ;


}

break;


case 7:

if (strstr(strlwr(prod.notes),keyword) != NULL) {

//запис в тимчасовий файл знайденого поля

fwrite(&prod,sizeof(Product),1,tmpstream);

count ;

}

break;



}

}

fclose(instream);



fclose(tmpstream);

return count;

}
Функція int dbf_sort(char *filename, int field) – призначена для сортування записів в файлі за алфавітом та за необхідним полем.

Абе́тка (А́збука, Алфаві́т) (грец. Αλφάβητο, лат. Abecedarium) - розташована в певному порядку сукупність літер, що застосовуються для запису певної мови.
Тобто всі записи, які відсортовані за заданим полем, записуються в динамічний масив структур product типу Product. Далі дані з цього масиву записуються в тимчасовий файл temp_filename_s.
Код даної функції має такий вигляд:
int dbf_sort(char *filename, int field)

{

//відкриваємо файл для читання

FILE *instream = fopen(filename ,"rb");

//відкриваємо тимчасовий файл для запису

FILE *tmpstream = fopen(temp_filename_s,"wb");

Product prod;

char *pr, *num;

memset(&prod,0,sizeof(Product));



//визначення довжини файлу

fseek(instream, 0L, SEEK_END);

int flen = ftell(instream)/sizeof(Product);

fseek(instream, 0L, SEEK_SET);

int kk,ff=flen;

Product *product;//об’являємо динамічний масив структур

Product vrem; //dopomigna zminna

//виділяємо для нього пам’ять розміром flen*sizeof(Product) байтів:

product=(Product*)malloc(flen*sizeof(Product));



//зчитування з файлу даних в масив

fread( product,sizeof(Product),flen,instream );

int count = 0;

do

{



kk=0;

ff--;


count ;

for (int i = 0 ; i < ff; i )

{

switch (field)



{

case 1:


//порівнюємо, який з 2-х рядків за алфавітом перший

if(strcmp(strlwr(product[i].code),

strlwr(product[i 1].cod e)) >0)

{

vrem=product[i];//запис в тимчасову змінну



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 2:

if (strcmp(strlwr(product[i].tovar),strlwr(product[i 1].tovar)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 3:

if (strcmp(strlwr(product[i].producer),strlwr(product[i 1].producer)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 4:

if (strcmp(strlwr(product[i].discription),strlwr(product[i 1].discription)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 5:

if (strcmp(strlwr(product[i].price),strlwr(product[i 1].price)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 6:

if (strcmp(strlwr(product[i].number),strlwr(product[i 1].number)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



case 7:

if (strcmp(strlwr(product[i].notes),strlwr(product[i 1].notes)) > 0)

{

vrem=product[i];



product[i]=product[i 1];

product[i 1]=vrem;

count ; kk ;

}

break;



}

}

} while( kk > 0 );


//запис в тимчасовий файл даних з масиву структур

fwrite(product,sizeof(Product),flen,tmpstream);

fclose(instream);

fclose(tmpstream);

free(product);

return count;

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


  1. Що являє собою база даних?

  2. Назвіть головні особливості програм для роботи з базами даних?

  3. Які задачі необхідно розв’язати при розробці програм для роботи з базами даних?

  4. Назвіть основні етапи проектування бази даних?

  5. Напишіть приклад структури бази даних?

  6. Як створити файл бази даних?

  7. Як здійснити зчитування даних з файлу?

  8. Як здійснити запис даних у файл?

  9. Для чого в структурі бази даних використовується об'єднання union?

  10. Які ви знаєте функції для роботи з базою даних?

  11. Як здійснити сортування записів у файлі бази даних?

  12. Як підключити до програми файл бази даних?

7.5 Практикум з програмування





  1. Напишіть фрагмент програми для додавання записів в базу даних.

  2. Напишіть фрагмент програми для редагування записів в базі даних.

  3. Напишіть фрагмент програми для видалення записів з бази даних.

  4. Напишіть фрагмент програми для створення порожнього файлу бази даних.

  5. Напишіть фрагмент програми для зчитування даних з файлу бази даних.

  6. Напишіть фрагмент програми для запису даних у файл бази даних.

  7. Напишіть фрагмент програми для сортування записів в файлі у алфавітному порядку та за необхідним полем.

  8. Напишіть фрагмент програми для видалення запису за заданим номером з файлу.

8 ОСОБЛИВОСТІ СТВОРЕННЯ ГРАФІЧНОГО МЕНЮ


АЛГОРИТМІЧНОЮ МОВОЮ С
8.1 Загальні відомості
Для створення графічного меню насамперед необхідно підключити бібліотеку graphics.h за допомогою препроцесорної директиви #include. Також потрібно підключити стандартні бібліотеки:
#include

#include

#include

#include>


Щоб ініціалізувати графічний режим використовуємо функцію

void GR_init()

void GR_init()

{

//знаходимо графічний драйвер



int gdriver=DETECT,gmode,errormode;

//ініціалізуємо графічний режим

initgraph(&gdriver,&gmode,"");

}
Для прикладу розглянемо алгоритм створення графічного меню програми автоматизації праці диспетчера торгової фірми з отримання та виконання замовлень від клієнтів.



Рисунок 8.1 – Приклад вікна програми з графічним меню
8.2 Створення кнопок
Спочатку доцільно розглянути алгоритм створення кнопки та логіку зміни її стану.

Рисунок 8.2 – Активна кнопка в меню
Кнопку можна створити за допомогою функції

void GR_draw_button(struct menu_button menu),

де struct menu_button menuструктура, в якій описані необхідні параметри кнопки. Тому розглянемо структуру struct menu_button :
struct menu_button

{

int x0;// абсциса верхнього лівого кутка



int y0;//ордината верхнього лівого кутка

int x1; // абсциса нижнього правого кутка

int y1; //ордината нижнього правого кутка

char label[10];//назва кнопки

int status;//стан кнопки, пасивний(0) чи активний(1)

};
Розглянемо саму функцію:

void GR_draw_button(struct menu_button menu)

{

int x0 = menu.x0;//задаємо координати кутків кнопки



int y0 = menu.y0;

int x1 = menu.x1;

int y1 = menu.y1;

int state= menu.status;//задаємо стан кнопки

char text_label[10]={" "};

strcpy(text_label,menu.label);

setcolor(8);//задаємо колір 8 – темносірий колір

rectangle(x0,y0,x1,y1);//рисуємо прямокутник за вхідними параметрами

setfillstyle(SOLID_FILL,7); //задаємо стиль заливання, а саме: однотонний світлосірого кольору

floodfill((x0 x1)/2,(y0 y1)/2,8); //зафарбовуємо раніше нарисований //прямокутник нарисований кольором 8

setcolor(0);//задаємо колір такий, як фон, оскільки фон у нас чорного кольору, //то олівець також має чорний колір

settextstyle(SMALL_FONT,HORIZ_DIR,0);//задаємо стиль тексту

outtextxy(x0 4,((y0 y1)/2)-5,text_label);//створюємо графічний текст //заданого стилю, тобто рисуємо назву кнопки

setcolor(7);//задаємо колір границь кнопки

line(x0,y1,x0,y0);//ліва вертикальна границя

line(x0,y0,x1,y0);//верхня горизонтальна границя

line(x0,y1,x1,y1);//нижня границя

line(x1,y0,x1,y1);//права границя

if(!state) //якщо кнопка неактивна, тобто не натиснута

{setcolor(15);

line(x0,y1,x0,y0);

line(x0,y0,x1,y0);

setcolor(8);

line(x1,y0,x1,y1);

line(x0,y1,x1,y1);

}

else {



// якщо кнопка активна, то рисуємо відповідно границі навпаки

setcolor(7);

settextstyle(SMALL_FONT,HORIZ_DIR,0);

//рисуємо текст трохи нижче, створюючи ефект об’єму, немов кнопка

//вгнулась вниз

outtextxy(x0 4,((y0 y1)/2)-5,text_label);

//тут відповідно рисуємо границі навпаки відносно неактивного стану

setcolor(1);

settextstyle(SMALL_FONT,HORIZ_DIR,0);

outtextxy(x0 6,((y0 y1)/2)-3,text_label);

setcolor(8);

line(x0,y1,x0,y0);

line(x0,y0,x1,y0);

setcolor(15);

line(x1,y0,x1,y1);

line(x0,y1,x1,y1);

}

}

8.3 Створення графічного підменю





Розглянемо алгоритм створення графічного підменю, яке з’являється відразу після натискання клавіші Enter під активною кнопкою. Відповідно для кожної кнопки створюються різні підменю.

Рисунок 8.3 – Виділення графічного підменю
Підменю можна створити за допомогою функції

void GR_draw_submenu(struct submenu smenu),

де struct submenu smenu – містить структуру підменю.
struct submenu

{

int items_number;//кількість пунктів в підменю



char labels[menu_max_items][menu_max_chars];//масив назв пунктів підменю

int x0;//початкова абсциса підменю, лівий верхній куток підменю

int y0;//початкова ордината підменю, лівий верхній куток підменю

int state;// стан підменю, пасивний чи активний

int active_element;//номер активного пункту в підменю

};

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



menu_max_chars // константа, що вказує на максимальний розмір назви пункту в підменю
void GR_draw_submenu(struct submenu smenu)

{

setcolor(8);



int

hpe=30,//висота в пікселах одного пункту підменю

items=smenu.items_number 1,//кількість пунктів меню

item_heigth=items*hpe,//висота в пікселах всіх пунктів меню

x0=smenu.x0,//початкова абсциса (Х-координата) верхнього лівого кутка

y0=smenu.y0,//початкова ордината (У-координата)верхнього лівого кутка

res_x_pos =x0 100,//права Х-координата підменю (х0 ширина)

res_y_pos =y0 item_heigth,// нижня У-координата підменю (у0 висота) res_y0_pos=y0 30,//початкова У-координата підменю

state =smenu.state,// стан підменю, 1- активний, 0 - пасивний

element= smenu.active_element;//номер вибраного пункту підменю

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

if (state)

{ //рисування прямокутника

rectangle(x0,res_y0_pos,res_x_pos,res_y_pos);

setfillstyle(SOLID_FILL,7);//fill style

//зафарбовуємо прямокутник вище заданим заливанням

floodfill(x0 1,res_y0_pos 1,8);

//Рисуємо тінь підменю

setcolor(0);

line(x0,res_y_pos 1,res_x_pos 1,res_y_pos 1);

line(res_x_pos 1,res_y_pos 1,res_x_pos 1,res_y0_pos 1);

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

settextstyle(SMALL_FONT,HORIZ_DIR,0);

//в циклі рисуємо послідовно всі пункти даного підменю.

// step – У-координата поточного підпункту

for(int i=0,step =y0 hpe; i

{ setcolor(8);

line(x0,step,res_x_pos,step);

setcolor(0);

char *str= smenu.labels[i];

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

if(element==i&&element>-1&&element<=items)

{

setcolor(14);



outtextxy(x0 4,step 10,str);

}

outtextxy(x0 4,step 10,str);



}}

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

else

{

setcolor(main_bgcolor);



rectangle(x0,res_y0_pos,res_x_pos 1,res_y_pos 1);

setfillstyle(SOLID_FILL,main_bgcolor);

floodfill(x0 2,res_y0_pos 2,main_bgcolor);

}}

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



Рисунок 8.4 – Графічне вікно пункту меню BD
В залежності від вибраної бази даних в головному базовому вікні відображаються різні дані. Ці дані можуть мати певну структуру в залежності від поставленої задачі та функціональності програми, тому розглянемо лише базове вікно та функцію, за допомогою якої воно створюється, а саме: функцію void DrawWorkWindow(int number_base,char *baza_name).

Вхідні параметри функції:

int number_baseномер бази даних, який служить для відтворення назви бази даних в кутку вікна і не є необхідним, був введений у зв’язку зі специфікою програмного продукту.

Відтво́рення - слово, яке, в залежності від контексту застосування набуває різних значень.

char *baza_nameназва операції, або назва пункту в підменю. Тобто це назва вікна, що виводиться по середині вікна



Рисунок 8.5 – Назва бази даних в меню


Рисунок 8.6 – Назва вікна
void DrawWorkWindow(int number_base,char *baza_name)

{

//рисуємо зафарбований прямокутник та границі вікна



setfillstyle(1,7);

int y0=40,

y1=getmaxy()-25;

bar(0,y0,getmaxx(),y1);

setcolor(15);

line(0,y0,getmaxx(),y0);

line(0,y0,0,y1);

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

setcolor(1);

setfillstyle(1,2);

bar(3,y0 6,635,y0 20);

setfillstyle(1,10);

bar(320-4*strlen(baza_name)- 16,y0 8,320 8*strlen(baza_name)/2 16,y0 16);

setfillstyle(1,14);

bar(320-4*strlen(baza_name)-8,y0 4,320 8*strlen(baza_name)/2 8,y0 20);

setcolor(0);

outtextxy(getmaxx()/2-8*strlen(baza_name)/2,y0 10,baza_name);

//в залежності від номера бази відображаємо на екран відповідний текст.

switch(number_base)

{

case 1:



setcolor(0); //задаємо чорнй колір

outtextxy(6,y0 12 1,"Product Base");

setcolor(15);//задаємо білий колір

outtextxy(5,y0 12,"Product Base");

break;

case 2:


setcolor(0); //задаємо чорнй колір

outtextxy(6,y0 12 1,"Klient Base");

setcolor(15); //задаємо білий колір

outtextxy(5,y0 12,"Klient Base");

break;

case 3:


setcolor(0); //задаємо чорнй колір

outtextxy(6,y0 12 1,"Zamovlennya Base");

setcolor(15); //задаємо білий колір

outtextxy(5,y0 12,"Zamovlennya Base");

break;

}

}



8.4 Створення діалогових вікон


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

Так, для запиту про введення інформації про новий продукт необхідно створити окреме вікно, яке показано на рисунку 8.7.



Рисунок 8.7 – Приклад діалогового вікна
Це вікно створюється за допомогою функції int GR_draw_ask(char *vopros)

Дана функція повертає значення 0 або 1 в залежності від дій користувача.

char *voprosтекст, що відображається у вікні

int GR_draw_ask(char *vopros)

{

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



setfillstyle(1,7);

bar(150,100,300,230);

//виведення тексту в вікні

setcolor(1);

outtextxy((450-8*strlen(vopros))/2,100 30,vopros);

//рисуємо границі вікна

setcolor(15);

line(150,230,150,100);

line(150,100,300,100);

setcolor(0);

line(300,100,300,230);

line(300,230,150,230);

//створення масиву структур кнопок даного вікна

struct menu_button ask[2]=

{

{160,180,210,200," Tak",0},



{230,180,280,200," Ni",0}

};

char chouse;//змінна, призначена для отримання коду з клавіатури і, в залежності від нього, переходу між кнопками



int cursor_pos=0;//позиція курсора

ask[cursor_pos].status=1;//задаєм активний стан кнопки «так»

//В циклі рисуємо кнопки з використанням нашої функції

for(int i=0;i<2;i )

{

GR_draw_button(ask[i]);//створення кнопки за заданою структурою



}

//виконуємо цикл, поки не введемо Enter або Esc

do

{

chouse=getch();//зберігаємо код клавіші з клавіатури



switch(chouse)

{

case 77://якщо код дорівнює клавіші права стрілка



if ((cursor_pos)==0) //якщо номер курсора нуль

{

cursor_pos ;//збільшуємо номер курсора



ask[cursor_pos].status=1;//задаємо активний статус //відповідній кнопці

GR_draw_button(ask[cursor_pos]);//перерисовуємо //активну кнопку

ask[cursor_pos-1].status=0;//задаємо пасивний статус //попередній кнопці

GR_draw_button(ask[cursor_pos-1]);//перерисовуємо //попередню кнопку

}

break;


case 75://якщо натиснута кнопка з лівою стрілкою

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

if(cursor_pos == 1)

{

cursor_pos--;



ask[cursor_pos].status=1;

GR_draw_button(ask[cursor_pos]);

ask[cursor_pos 1].status=0;

GR_draw_button(ask[cursor_pos 1]);

}

break;


}

//цикл виконується поки не була натиснута клавіша Enter або Esc

}while(chouse!=13 && chouse!=27);

//перевіряємо, якщо позиція курсора на кнопці «Так» або натиснута клавіша Enter, то функція повертає значення 1

if (cursor_pos==0 && chouse==13)

return 1;

//інакше функція повертає значення 0

else return 0;

}
Для введення ключового слова до пошуку номера запису розроблено спеціальне діалогове вікно (як базове), приклад якого зображено на рисунку 8.8.

Рисунок 8.8 – Приклад діалогового вікна
Діалогове вікно програмно реалізується за допомогою функції:
void DrawWindow(int x0,int y0,int x1,int y1,char *head),

де

int x0, int y0координати лівого верхнього кутка вікна;



int x1, int y1 координати правого нижнього кутка вікна;

char *headтекст, що відображається у верхній частині вікна;


Функція може містити такі оператори:

void DrawWindow(int x0,int y0,int x1,int y1,char *head)

{

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



setfillstyle(1,7);
Сірий колір - це ахроматичний колір, точніше - множина всіх кольорів, отримуваних шляхом поєднання трьох основних кольорів - червоного, зеленого і синього - в рівних концентраціях. Залежно від яскравості відтінок сірого міняється від чорного (яскравість 0%) до білого (яскравість 100%).

bar(x0,y0,x1,y1);

//рисуємо границі вікна

setcolor(15);

//білі границі

line(x0,y1,x0,y0);

line(x0,y0,x1,y0);

setcolor(0);

//чорні границі

line(x1,y0,x1,y1);

line(x0,y1,x1,y1);

// рисування рамки

setcolor(0);

rectangle(x0 5,y0 5,x1-5,y1-5);

//зафарбовування верхньої частини рамки як основи для виведення тексту

bar((x0 x1-8*strlen(head))/2-8,y0 2,(x0 x1 8*strlen(head))/2 8,y0 20);

//виведення тексту (заголовок вікна)

outtextxy((x0 x1-8*strlen(head))/2,y0 3,head);

//рисування тіні вікна

setcolor(0);

line(x1 1,y0,x1 1,y1);

line(x0,y1 1,x1,y1 1);

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

int VvodNumber(int x0, int y0,char *vopros),

та може мистити таки вхідні дані:

int x0, int y0координати верхнього лівого кутка вікна;

char *voprosзаголовок вікна.

Вихідним параметром такої функції може бути параметр типу int.

Функція може містити такі оператори:

int VvodNumber(int x0, int y0,char *vopros)

{

char *str=vopros;//записуємо текст вікна



int i=0;//індекс

char cc;//символ введення

*nzz;//тимчасовий рядок для редагування введеного числа

//кінцеві координати визначаються з довжини тексту

int xcur=x0 8*strlen(str);//початкова Х-координата довжина в пікселах слова за умови, що один символ=8

int ycur=y0;

//створення діалогового вікна

DrawWindow(x0-20, y0-40, xcur 8*5 20, y0 20, "Vvedenya nomeru");


//виведення тексту вікна

setcolor(1);

outtextxy(x0,y0,str);
//в циклі отримуємо код натиснутої клавіші і рисуємо символ підкреслення

while(cc!=13)

{

while(!kbhit())//поки не були натиснуті клавіші з клавіатури



{

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

setcolor(1);//задаємо чорний колір

//знак підкреслення

line(xcur 8*(i),ycur 8,xcur 8*(i 1),ycur 8);

delay(50);//затримка на 50 мілісекунд

setcolor(7);

Секу́нда (скорочено с.) - одиниця виміру часу у СІ (колишня МКС) та системі СГС.
//задаємо сірий колір (колір фону)

line(xcur 8*(i),ycur 8,xcur 8*(i 1),ycur 8); //знову рисуємо знак підкреслення

delay(50);//затримка на 50 мілісекунд

}

cc=getch();//зберігаємо код клавіші з клавіатури



setcolor(4);//задаємо колір тексту

//перевірка на те чи не було введено


//Backspace (код 8) чи 0 спочатку і чи не було введено більше ніж 5 символів

//якщо так, то повертаємось на початок циклу

if((cc==8 && i==0) || (cc!=8&&i>=5) || (cc=='0' && i==0))

{

continue;



}

//якщо введений Backspace (код 8), то в рядку видаляємо останній символ і зафарбовуємо його на екрані сірим кольором, тобто кольором фону

if(cc==8&&i!=0)

{

nzz[i]=NULL;//поточний символ видаляється з рядка



nzz[i-1]=NULL;//попередньо введений символ видаляється з рядка

setfillstyle(1,7);

bar(xcur 8*(i-1),ycur,xcur 8*(i),ycur 8);

//зафарбовуємо попередній символ

i--;//зменшуємо індекс рядка

}

//якщо введені цифри



if(cc>=48&&cc<=57&&i<5)

{

nzz[i]=cc;//записуємо в рядок введений символ



i ;//збільшуємо індекс

nzz[i]='\0';//записуємо спец символ в кінець рядка для коректної роботи з ним

outtextxy(xcur,ycur,nzz);// виводимо на екран даний рядок

}

}



return atoi(nzz)-1;//конвертуємо даний рядок в число типу int та повертаємо отриманий результат (вихідні дані)

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

char *VvodSlovo(int x0, int y0,char *vopros) – така функція типу char *.
Щоб очистити робочу область можна використати функцію void clean_workspace(), яка зафарбовує робочу область фоновим кольором, наприклад, таку функцію:
void clean_workspace()

{

setcolor(main_bgcolor 1);//задаєм колір, де main_bgcolor - константа



setfillstyle(SOLID_FILL,main_bgcolor);//задаємо стиль заливання

//зафарбовуємо робочу область

bar(0,topmargin,getmaxx(),getmaxy());

setcolor(15);

//виводимо текст як допомогу для користувача

outtextxy(200,300,"Viberity Bazu danih v punkti BD");

outtextxy(5,465,"Press buttons: Up, Down, Left, Right, 'Enter'-enter, 'Esc'-exit,'F10'-main menu ");

}
Для більш глобального очищення екрана та встановлення базових параметрів можна використовувати функцію void GR_set_base_params(), структура якої наведена нижче.

void GR_set_base_params()

{

setcolor(1);



setfillstyle(1,7);

//зафарбовуємо весь екран

floodfill(1,1,main_bgcolor);

}
Для роботи з такими базовими функціями, що створюють графічні елементи, можна розробити досить просту головну функцію MyMenu(), в якій прописана логіка роботи графічного меню. Розглянемо детально структуру такої функції.


int MyMenu()

{

char ch;//поточний введений символ



//позиція курсора в головному меню (поточна активна кнопка)

int cursor_position=0;

int cursor_can_move_lr=1;//прапорець рухомості курсора

int submenu_cursor_position=0;//позиція курсора в підменю

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

int old_cursor_position=cursor_position;

int old_submenu_cursor_position=submenu_cursor_position;

//присвоюємо поточну позицію

int free_window=0;//прапорець на звільнення вікна

//вказівник на номер бази даних (динамічна змінна)

int *nbd;

Звільнення - в трудовому праві припинення трудових відносин між працівником і роботодавцем.

//виділення пам’яті для номера бази даних

nbd = (int*)malloc(sizeof(int));

//присвоюємо 0-й номер

*nbd=0;

//ініціалізація графіки

GR_init();

//задаємо базові параметри

GR_set_base_params();

//очищаємо робочу область

clean_workspace();

setcolor(1);

//задаємо масив структур для кнопок

menu_button buttons[n_buttons]={

{10,10,80,30,"BD",0},

{90,10,90 70,30,"View",0},

{160 10,10,160 10 70,30,"Edit",0},

{230 20,10,230 20 70,30,"Program",0},

};

//задаємо масив структур для всіх підменю відповідно для кнопок



submenu pull_down_menu[n_buttons]={

{3,{"Tovar","Kliyent","Nakladna"},0,0,0,0},

{2,{"Sort","Poshuk"},0,0,0,0},

{3,{"Delete","Add","Rewrite"},0,0,0,0},

{3,{"About","Avtor","Quit",},0,0,0,0}

};

//в циклі передаємо в функцію кожен елемент масиву структур



// і рисуємо таким чином кнопки

for(int i=0;i

GR_draw_button(buttons[i]);

//аналізуємо введені дані з клавіатури

do

{

ch=getch();



//записуємо код клавіші

//перевіряємо на відповідні коди

switch(ch)

{

case 68:// F10 Pressed



//робимо поточну кнопку неактивною

buttons[cursor_position].status=0;

//перерисовуємо кнопку

GR_draw_button(buttons[cursor_position]);

cursor_can_move_lr=1;

//встановлюємо прапорець можливості руху курсора на 1 – активний

cursor_position=0;

//збиваємо позицію курсора на першу кнопку (0)

buttons[cursor_position].status=1;

//задаємо статус першій кнопці

GR_draw_button(buttons[cursor_position]);

// перерисовуємо кнопку

break;

case 77://Right side movement



// якщо введена права стрілка

//якщо позиція курсора не більше максимальної

//якщо курсор маже рухатись
if ((cursor_position 1)<(n_buttons)&&cursor_can_move_lr)

{

//збільшуємо величину курсора на 1 (номер кнопки)



cursor_position ;

//перерисовуємо нову кнопку на активну

buttons[cursor_position].status=1;

GR_draw_button(buttons[cursor_position]);

//перерисовуємо попередню кнопку на неактивну

buttons[cursor_position-1].status=0; Gdraw_button(buttons[cursor_position-1]);

}

break;


case 75://Left side movement

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

if(cursor_position !=0 && cursor_can_move_lr)

{

if(cursor_position-1!=n_buttons)



cursor_position--;

buttons[cursor_position].status=1;

GR_draw_button(buttons[cursor_position]);

buttons[cursor_position 1].status=0;

GR_draw_button(buttons[cursor_position 1]);

}

break;



//при введенні Enter створюється підменю

case 13://Enter key

buttons[cursor_position].status=1;

GR_draw_button(buttons[cursor_position]);

//вимикаємо рухливість курсора

//рисуємо відповідне меню

pull_down_menu[cursor_position].

Рухливість носіїв заряду або мобільність носіїв заряду - кількісна характеристика носія заряду, яка визначає його вклад у провідність.
state=1; //активуємо поточне підменю

//задаємо координати підменю такі, як координати кнопки

pull_down_menu[cursor_position].x0=buttons[cursor_position].x0;

pull_down_menu[cursor_position].y0=buttons[cursor_position].y0;

//рисуємо вибране підменю

GR_draw_submenu(pull_down_menu[cursor_position]);

char chr;

//встановлюємо номер вибраного пункту (курсор підменю) на

//перший

submenu_cursor_position=0;

//аналізуємо введені символи з клавіатури

do


{

//записуємо код клавіші

chr=getch();

//перевіряємо введені символи


switch(chr)

{

//якщо введена клавіша Escape, то ми знищуємо дане підменю



//тобто виходимо з підменю в головне меню

case 27://If Escape pressed

pull_down_menu[cursor_position].state=0;

GR_draw_submenu(pull_down_menu[cursor_position]);

cursor_can_move_lr=1;

//дозволяємо рухатись курсору в сторони

//очищуємо робочу область

clean_workspace();

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

if(free_window)

//дана функція призначена для виконання певної операції при виборі певного пункту підменю execute_clik(nbd,old_cursor_position,old_submenu_cursor_position);

break;


//якщо натиснута стрілка вниз

case 80://If down button pressed

//перевіряємо, чи позиція курсора не більша за допустиму if(pull_down_menu[cursor_position].items_number>submenu_cursor_position)

submenu_cursor_position ;

//якщо більша, то повертаємось на початок

if(pull_down_menu[cursor_position].items_number<=submenu_cursor_position) submenu_cursor_position=0;

//перерисовуємо підменю з новим вибраним пунктом

pull_down_menu[cursor_position].active_element=submenu_cursor_position;

GR_draw_submenu(pull_down_menu[cursor_position]);

break;


//якщо натиснута стрілка вверх, виконуємо аналогічні дії

//як і при натисканні клавіші зі стрілкою вниз, але рухаємось в іншому напрямку

case 72://If up button pressed

if (0>=submenu_cursor_position)

submenu_cursor_position=pull_down_menu[cursor_position].items_number;

if(submenu_cursor_position>0)

submenu_cursor_position--;

//submenu

pull_down_menu[cursor_position].active_element=submenu_cursor_position;

GR_draw_submenu(pull_down_menu[cursor_position]);

break;

//якщо введена клавіша Enter



case 13:

buttons[cursor_position].status=0;

//задаємо пасивний статус поточній кнопці

//задаємо пасивний статус підменю, стираємо підменю (перерисовуємо в пасивному стані) та перерисовуємо кнопку

pull_down_menu[cursor_position].state=0;

GR_draw_button(buttons[cursor_position]);

GR_draw_submenu(pull_down_menu[cursor_position]);

//очищуємо робочу область

clean_workspace();

//виконуємо необхідну операцію в залежності від вибраного пункту в підменю

execute_clik(nbd,cursor_position,submenu_cursor_position);

old_cursor_position=cursor_position,

old_submenu_cursor_position=submenu_cursor_position;

//встановлюємо прапорець 1 – так

free_window=1;

//присвоюємо символу значення 27 для виходу з циклу

chr=27;

ch=75;


break;

}

} while(chr!=27);



//цикл виконується поки не була введена клавіша

//Esc або не вибраний пункт в підменю

break;

}

} while(ch!=27);



//виходимо з програми, натиснувши клавішу Esc

free(nbd);

//очищуємо екран

cleardevice();

//закриваємо графіку

closegraph();

return 0;

}


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


  1. Як створюються кнопки в графічному меню?

  2. З якою метою створюються діалогові вікна? Як це реалізувати?

  3. Як створити просто діалогове вікно з вибором кнопки «ТАК» чи «НІ» для руху по програмі?

  4. Як зафарбувати робочу область фоновим кольором?

  5. Як задається стиль тексту, яким ми відображуємо пункти меню?

  6. Як відбувається аналіз даних, введених з клавіатури?
    Аналіз даних - розділ математики, що займається розробкою методів обробки даних незалежно від їх природи.


  7. Як забезпечити неперервне виконання циклу до тих пір, поки не буде натиснута клавіша?

  8. Як забезпечується рух по пунктах меню?

  9. Яке призначення функції роботи з головним меню?

8.6 Практикум з програмування


  1. Написати фрагмент програми для створення вікна за заданими координатами.

  2. Написати фрагмент програми для створення вікна з подвійною рамкою.

  3. Написати фрагмент програми, в якому б задавалася кількість пунктів меню.

  4. Розробити фрагмент програми, яка б створювала рядок горизонтального меню.

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

  6. Написати фрагмент програми для створення вікна висхідного меню.

  7. Написати фрагмент програми для здійснення руху по пунктах підменю.

СЛОВНИК ТЕРМІНІВ
1   2   3   4   5   6   7   8   9   10   11



  • № поля