One_Record::One_Record(int handle,One_Record * lst) {
char rs[140]
// Чтение во временную строку
read(handle,rs,140)
strcpy(fio,rs)
strcpy(yy,rs+60)
strcpy(addr,rs+65)
strcpy(grp,rs+125)
next=NULL
last=lst
if (!eof(handle))
next=new One_Record(handle,this)
}
// Записьданныхфайл
void One_Record::save(int handle) {
char rs[140]
strcpy(rs,fio)
strcpy(rs+60,yy)
strcpy(rs+65,addr)
strcpy(rs+125,grp)
_write(handle,rs,140)
if (next!=NULL) next->save(handle)
}
// Добавлениезаписивсписок
void One_Record::add(One_Record * a) {
// Проверка, дальше ли запись по алфавиту
if (strcmp(a->fio,fio)<0) {
// Вставка перед этим элементом
if (last!=NULL) {
a->last=last
a->next=this
last->next=a
last=a
} else {
a->next=this
a->last=NULL
last=a
}
// Дальше - либо добавление в конец, либо переход к следующему
} else if (next!=NULL) next->add(a)
else {
next=a
a->last=this
a->next=NULL
}
}
// Найти вверх по списку элемент, попадающий под маску
One_Record * One_Record::FindUp(char * m_fio,char * m_yy,char * m_addr,char * m_grp) {
if (stc(fio,m_fio)&&
stc(fio,m_fio)&&
stc(fio,m_fio)&&
stc(fio,m_fio)) return this
if (last!=NULL) return last->FindUp(m_fio,m_yy,m_addr,m_grp)
else return NULL
}
// Найти вниз по списку элемент, попадающий под маску
One_Record * One_Record::FindDown(char * m_fio,char * m_yy,char * m_addr,char * m_grp) {
if (stc(fio,m_fio)&&
stc(yy,m_yy)&&
stc(addr,m_addr)&&
stc(grp,m_grp)) return this
if (next!=NULL) return next->FindDown(m_fio,m_yy,m_addr,m_grp)
else return NULL
}
// Классокон ---------------------------------------------
// Конструктор
wind::wind(int ix,int iy,int idx,int idy) {
x=ix
y=iy
dx=idx
dy=idy
pap=8
ink=15
apap=1
ts=1
next=NULL
}
// Перерисовка
void wind::redr() {
setfillstyle(1,pap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
if (next!=NULL) next->redr()
}
// Добавление в список
void wind::add(void * p) {
if (next!=NULL) next->add(p)
else next=(wind *) p
}
// Активизация
void * wind::active() {
// Проверка, активизировать ли
if (ts) {
// Прорисовка активного состояния
setfillstyle(1,apap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
char c
// Обработка клавиатуры - TAB - следующее, ESC - выход
do {
c=getch()
} while ((c!=9)&&(c!=27))
if (c==27) f_exit=1
return next
} else return next
// Нет - вернуть указатель на следующее
}
// Изменениефлага TS
void wind::setact(char a) {
ts=a
}
// Класс строк редактирования -----------------------------
// Конструктор
ed_win::ed_win(int ix,int iy,int idx,int idy,char * p,int mln):
wind(ix,iy,idx,idy) {
maxlen=mln
strcpy(capt,p)
strcpy(pcapt,p)
}
// Перерисовка
void ed_win::redr(){
setfillstyle(1,pap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
settextjustify(1,1)
outtextxy(x+dx/2,y+dy/2,capt)
if (next!=NULL) next->redr()
}
// Активизация
void * ed_win::active(){
unsigned char c
char ps[200]
if (!ts) return next
// Проверка, активизировать или пропустить
// Перерисовка
setfillstyle(1,apap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
settextjustify(1,1)
do {
// Вывод строки с символом "_" в качестве курсора
strcpy(ps,capt)
strcat(ps,"_")
bar(x+4,y+4,x+dx-4,y+dy-4)
outtextxy(x+dx/2,y+dy/2,ps)
// Опросклавиатуры
c=getch()
if (c==0) c=getch()
else {
if (c==8) {
// Удалить - переместить конец строки 0 на единицу левее
if (strlen(capt)>0) capt[strlen(capt)-1]=0
}
if (c==13) strcpy(pcapt,capt)
// ENTER - запомнить содержимое
if (c==27) strcpy(capt,pcapt)
// ESC - восстановить содержимое
if ((c>32)&&(strlen(capt)<maxlen)) {
// Иначе - добавить символ
capt[strlen(capt)+1]=0
capt[strlen(capt)]=c
}
}
} while (c!=9)
return next
}
// Класскнопок -------------------------------------------
// Конструктор
bt_win::bt_win(int ix,int iy,int idx,int idy,char * p,void (*ifun)()):
wind(ix,iy,idx,idy) {
apap=12
pap=3
strcpy(capt,p)
fun=ifun
}
// Перерисовка
void bt_win::redr(){
setfillstyle(1,pap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
settextjustify(1,1)
outtextxy(x+dx/2,y+dy/2,capt)
if (next!=NULL) next->redr()
}
// Активизация
void * bt_win::active(){
char c
if (ts) {
// Перерисовка активной кнопки
setfillstyle(1,apap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
settextjustify(1,1)
outtextxy(x+dx/2,y+dy/2,capt)
// Обработка событий
do {
c=getch()
if (c==13) fun()
// ENTER - выполнение функции
} while ((c!=13)&&(c!=9)&&(c!=27)&&(!f_exit))
// Проверка условия завершения
if (c==27) f_exit=1
// Если ESC - выход из программы
}
return next
}
// Классскроллеров ---------------------------------------
// Конструктор
sc_win::sc_win(int ix,int iy,int idx,int idy,One_Record * ipnt,char * ifio,char * iyy,char * iaddr,char * igrp):
wind(ix,iy,idx,idy) {
apap=1
pap=1
strcpy(m_fio,ifio)
strcpy(m_addr,iaddr)
strcpy(m_yy,iyy)
strcpy(m_grp,igrp)
pnt=ipnt->FindDown(ifio,iyy,iaddr,igrp)
}
// Перерисовка
void sc_win::redr() {
int n
int dlt=dx/5
One_Record * p
// Перерисовка
setfillstyle(1,apap)
setcolor(ink)
bar(x,y,x+dx,y+dy)
rectangle(x+3,y+3,x+dx-3,y+dy-3)
settextjustify(1,1)
// Вывод всех строк таблицы
p=pnt
n=20
while ((p!=NULL)&&(n<dy)) {
outtextxy(x+dlt,y+n,p->fio)
outtextxy(x+dlt*2,y+n,p->yy)
outtextxy(x+dlt*3,y+n,p->addr)
outtextxy(x+dlt*4,y+n,p->grp)
// Попытканайтиследующийэлемент
if (p->next!=NULL) p=p->next->FindDown(m_fio,m_yy,m_addr,m_grp)
else p=NULL
n+=20
}
}
// Активизация
void * sc_win::active() {
char c
One_Record * p
do {
redr()
c=getch()
if (!c) c=getch()
if (c==72) if (pnt!=NULL) {
// Вверх
p=pnt->FindUp(m_fio,m_yy,m_addr,m_grp)
if (p!=NULL) pnt=p
}
if (c==80) if (pnt!=NULL) {
// Вниз
p=pnt->FindDown(m_fio,m_yy,m_addr,m_grp)
if (p!=NULL) pnt=p
}
} while (c!=27)
setfillstyle(3,4)
bar(0,0,639,479)
return next
}
// ТЕЛА ФУНКЦИЙ КНОПОК ----------------------------------------
// Выход - просто установка флага
void fun_exit() {
f_exit=2
}
// Вверх - перемещение указателя и перерисовка полей редактирования
void up() {
if (ctb!=NULL) if (ctb->next!=NULL) {
ctb=ctb->next
strcpy(ifio.capt,ctb->fio)
strcpy(iyy.capt,ctb->yy)
strcpy(iaddr.capt,ctb->addr)
strcpy(igrp.capt,ctb->grp)
edwin->redr()
}
}
// Вниз - перемещение указателя и перерисовка полей редактирования
void down() {
if (ctb!=NULL) if (ctb->last!=NULL) {
ctb=ctb->last
strcpy(ifio.capt,ctb->fio)
strcpy(iyy.capt,ctb->yy)
strcpy(iaddr.capt,ctb->addr)
strcpy(igrp.capt,ctb->grp)
edwin->redr()
}
}
// Удаление
void fun_del() {
if (ctb!=NULL) {
if (ctb->last==NULL) {
ndb=ctb->next
ctb->next->last=NULL
delete ctb
ctb=NULL
if (ndb==NULL) setfillstyle(3,4)
bar(0,0,639,479)
} else {
ctb->last->next=ctb->next
ctb->next->last=ctb->last
delete ctb
ctb=NULL
}
}
}
// Добавление
void fun_add() {
wind * act
act=edwin
One_Record * a
do {
edwin->redr()
act=(wind *) act->active()
if (act==NULL) act=edwin
} while (!f_exit)
if (f_exit==2) {
a=new One_Record(ifio.capt,iyy.capt,iaddr.capt,igrp.capt)
if (ndb==NULL) ndb=a
else {
ndb->add(a)
if (ndb->last!=NULL) ndb=ndb->last
}
}
f_exit=0
}
// Поиск
void find() {
act=edwin
if (ctb==NULL) return
do {
edwin->redr()
act=(wind *) act->active()
if (act==NULL) act=edwin
} while (!f_exit)
if (f_exit==2) {
sc_win a(10,100,500,300,ndb,ifio.capt,iyy.capt,iaddr.capt,igrp.capt)
a.active()
}
f_exit=0
}
// Редактирование
void edit() {
act=edwin
if (ctb==NULL) return
do {
edwin->redr()
act=(wind *) act->active()
if (act==NULL) act=edwin
} while (!f_exit)
if (f_exit==2) {
strcpy(ctb->fio,ifio.capt)
strcpy(ctb->yy,iyy.capt)
strcpy(ctb->addr,iaddr.capt)
strcpy(ctb->grp,igrp.capt)
}
f_exit=0
}
void about() {
cleardevice()
setfillstyle(6,5)
bar(0,0,639,479)
setfillstyle(1,0)
bar(100,100,539,379)
rectangle(100,100,539,379)
outtextxy(320,130," ОПРОГРАММЕ ")
getch()
setfillstyle(3,4)
bar(0,0,639,479)
}
// Основная программа
void main() {
int drv,mode
int handle
drv=DETECT
initgraph(&drv,&mode,"")
setfillstyle(3,4)
bar(0,0,639,479)
ed_win hlp(10,440,620,40,
" Выборпункта - TAB, Активизация - ENTER, Выход - ESC ",0)
hlp.setact(0)
// попытка считать базу данных
handle=open("base_o.dat",O_RDONLY|O_BINARY)
if (handle>=0) {
ndb=new One_Record(handle,NULL)
}
// Добавление в списки соответствующих окон
wind * stwin
stwin=(wind *) new ed_win(10,50,590,20," Student database ",5)
stwin->setact(0)
stwin->add(&hlp)
stwin->add(&add_w)
stwin->add(&del_w)
stwin->add(&edt_w)
stwin->add(&fin_w)
stwin->add(&ext_w)
stwin->add(&abt_w)
stwin->add(&up_w)
stwin->add(&down_w)
act=stwin
edwin=(wind *) new bt_win(250,300,100,20," OK ",fun_exit)
edwin->add(&ifio)
edwin->add(&iyy)
edwin->add(&iaddr)
edwin->add(&igrp)
// Обработка событий
do {
// Проверка, чтобы указатель на текущий при непустом списке всегда
// показывал на один из элементов
if (ctb==NULL) ctb=ndb
if (ctb!=NULL) {
strcpy(ifio.capt,ctb->fio)
strcpy(iyy.capt,ctb->yy)
strcpy(iaddr.capt,ctb->addr)
strcpy(igrp.capt,ctb->grp)
edwin->redr()
}
// Перерисовка
stwin->redr()
// Активизацияочередногоокна
act=(wind *) act->active()
if (act==NULL) act=stwin
} while (!f_exit)
closegraph()
// Запись в файл или его удаление при пустой базе
if (ndb!=NULL) {
handle=open("base_o.dat",O_WRONLY|O_TRUNC|O_CREAT|O_BINARY)
if (handle>=0) {
while (ndb->last!=NULL) ndb=ndb->last
ndb->save(handle)
} else perror(" Error: ")
} else {
remove("base_o.dat")
}
close(handle)
}