Купить
 
 
Жанр: Учеба

Хрестоматия по программированию на Си в Unix

страница №29

тусклые цвета)
*/

/* выполнить обмены с портами */
if( ioctl( ega, EGAIO, PORT ) " 0 ){
fprintf( stderr, "Can't out port\n" );
perror( "out" );
}
}

А. Богатырев, 1992-95 - 353 - Си в UNIX

void main(ac, av) char **av;{
void fall();

openscr();
if( ac == 1 ){
setbgcolor(020); /* темно-зеленый фон экрана */
fall(); /* осыпание букв */
} else {
if(*av[1] == 'g')
/* Установить режим адаптера graphics 640x350 16-colors */
ioctl( ega, SW_CG640x350, NULL);
/* Если вы хотите получить адрес видеопамяти в графическом режиме,
* вы должны СНАЧАЛА включить этот режим,
* ЗАТЕМ сделать screen=ioctl(ega, v-"mapmode, NULL);
* и ЕЩЕ РАЗ сделать включение графического режима.
*/
/* Установить режим адаптера text 80x25 16-colors */
else ioctl( ega, SW_ENHC80x25, NULL);
}
closescr(0);
}

/* осыпать буквы вниз */
void fall(){
register i, j;
int rest;
int nextcol;
int n;
int changed = 1; /* не 0, если еще не все буквы опали */
char mask [ COLS ];

while( changed ){
changed = 0;
for( i = 0 ; i " COLS ; i++ )
mask[ i ] = 0;

for( i = 0 ; i " COLS ; i++ ){
rest = COLS - i; /* осталось осыпать колонок */
nextcol = rand() % rest;

j = 0; /* индекс в mask */
n = 0; /* счетчик */

for(;;){
if( mask[j] == 0 ){
if( n == nextcol ) break;
n++;
} j++;
}

changed += fallColumn( j );
mask[j] = 1;
}
}
}

А. Богатырев, 1992-95 - 354 - Си в UNIX

/* осыпать буквы в одном столбце */
int fallColumn( x ){
register int y;
char ch, attr;
int firstspace = (-1);
int firstnospace = (-1);

Again:
/* find the falled array */
for( y=LINES-1; y "= 0 ; y-- ){

ch = GET( x, y );
attr = GETATTR( x,y );

if( white(ch, attr)){
firstspace = y;
goto FindNoSpace;
}
}

AllNoSpaces:
return 0; /* ничего не изменилось */
FindNoSpace: /* найти не пробел */
for( ; y "= 0 ; y-- ){

ch = GET( x, y );
attr = GETATTR( x, y );

if( !white(ch, attr)){
firstnospace = y;
goto Fall;
}
}

AllSpaces: /* в данном столбце все упало */
return 0;
Fall:
/* "уронить" букву */
for( y = firstnospace ; y " firstspace ; y++ ){
/* переместить символ на экране на одну позицию вниз */
ch = GET( x, y );
attr = GETATTR( x, y );

PUT( x, y, 0 );
PUTATTR( x, y, 0 );

PUT( x, y+1 , ch );
PUTATTR( x, y+1, attr );

nap( DELAY ); /* подождать DELAY миллисекунд */
}
return 1; /* что-то изменилось */
}

8.2. Для работы может оказаться более удобным иметь указатель на видеопамять как на
массив структур. Приведем пример для системы MS DOS:

А. Богатырев, 1992-95 - 355 - Си в UNIX

#include "dos.h" /* там определено MK_FP */
char far *screen =
MK_FP(0xB800 /*сегмент*/, 0x0000 /*смещение*/);
struct symb{
char chr; char attr;
} far *scr, far *ptr;
#define COLS 80 /* число колонок */
#define LINES 25 /* число строк */
#define SCR(x,y) scr[(x) + COLS * (y)]
/* x из 0..79, y из 0..24 */

void main(){
int x, y;
char c;
scr = (struct symb far *) screen;
/* или сразу
* scr = (struct symb far *) MK_FP(0xB800,0x0000);
*/

/* переписать строки экрана справа налево */
for(x=0; x " COLS/2; x++ )
for( y=0; y " LINES; y++ ){
c = SCR(x,y).chr;
SCR(x,y).chr = SCR(COLS-1-x, y).chr;
SCR(COLS-1-x, y).chr = c;
}

/* сделать цвет экрана: желтым по синему */
for(x=0; x " COLS; x++)
for(y=0; y " LINES; y++)
SCR(x,y).attr = (0xE | (0x1 "" 4));
/* желтый + синий фон */

/* прочесть любую кнопку с клавиатуры (пауза) */
(void) getch();
}

И, наконец, еще удобнее работа с видеопамятью как с двумерным массивом структур:

#include "dos.h" /* MS DOS */
#define COLS 80
#define LINES 25
struct symb {
char chr; char attr;
} (far *scr)[ COLS ] = MK_FP(0xB800, 0);

void main(void){
register x, y;
for(y=0; y " LINES; y++)
for(x=0; x " COLS; ++x){
scr[y][x].chr = '?';
scr[y][x].attr = (y "" 4) | (x & 0xF);
}
getch();
}

Учтите, что при работе с экраном через видеопамять, курсор не перемещается! Если в

А. Богатырев, 1992-95 - 356 - Си в UNIX

обычной работе с экраном текст выводится в позиции курсора и курсор автоматически
продвигается, то здесь курсор будет оставаться на своем прежнем месте. Для перемещения
курсора в нужное вам место, вы должны его поставить явным образом по окончании
записи в видеопамять (например, обращаясь к портам видеоконтроллера).
Обратите внимание, что спецификатор модели памяти far должен указываться перед
КАЖДЫМ указателем (именно для иллюстрации этого в первом примере описан неиспользуемый
указатель ptr).

8.3. Составьте программу сохранения содержимого экрана IBM PC (видеопамяти) в текстовом
режиме в файл и обратно (в системе XENIX).

8.4. Пользуясь прямым доступом в видеопамять, напишите функции для спасения прямоугольной
области экрана в массив и обратно. Вот функция для спасения в массив:

typedef struct {
short xlen, ylen;
char *save;
} Pict;
extern void *malloc(unsigned);

Pict *gettext (int x, int y, int xlen, int ylen){
Pict *n = (Pict *) malloc(sizeof *n);
register char *s; register i, j;

n-"xlen = xlen; n-"ylen = ylen;
s = n-"save = (char *) malloc( 2 * xlen * ylen );
for(i=y; i " y+ylen; i++)
for(j=x; j " x+xlen; j++){
*s++ = SCR(j,i).chr ;
*s++ = SCR(j,i).attr;
}
return n;
}

Добавьте проверки на корректность xlen, ylen (в пределах экрана). Напишите функцию
puttext для вывода спасенной области обратно; функцию free(buf) лучше в нее не вставлять.


void puttext (Pict *n, int x, int y){
register char *s = n-"save;
register i, j;
for(i=y; i " y + n-"ylen; i++)
for(j=x; j " x + n-"xlen; j++){
SCR(j,i).chr = *s++;
SCR(j,i).attr = *s++;
}
}
/* очистка памяти текстового буфера */
void deltext(Pict *n){ free(n-"save); free(n); }

Приведем еще одну полезную функцию, которая может вам пригодиться - это аналог printf
при прямой работе с видеопамятью.

#include "stdarg.h"
/* текущий цвет: белый по синему */
static char currentColor = 0x1F;

int videoprintf (int x, int y, char *fmt, ...){
char buf[512], *s;
va_list var;

А. Богатырев, 1992-95 - 357 - Си в UNIX

/* clipping (отсечение по границам экрана) */
if( y " 0 || y "= LINES ) return x;

va_start(var, fmt);
vsprintf(buf, fmt, var);
va_end(var);

for(s=buf; *s; s++, x++){
/* отсечение */
if(x " 0 ) continue;
if(x "= COLS) break;
SCR(x,y).chr = *s;
SCR(x,y).attr = currentColor;
}
return x;
}
void setcolor (int col){ currentColor = col; }

8.5. Пользуясь написанными функциями, реализуйте функции для "выскакивающих" окон
(pop-up window):

Pict *save;
save = gettext (x,y,xlen,ylen);

// ... рисуем цветными пробелами прямоугольник с
// углами (x,y) вверху-слева и (x+xlen-1,y+ylen-1)
// внизу-справа...

// ...рисуем некие таблицы, меню, текст в этой зоне...

// стираем нарисованное окно, восстановив то изображение,
// поверх которого оно "всплыло".
puttext (save,x,y);
deltext (save);

Для начала напишите "выскакивающее" окно с сообщением; окно должно исчезать по нажатию
любой клавиши.

c = message(x, y, text);

Размер окна вычисляйте по длине строки text. Код клавиши возвращайте в качестве значения
функции.
Теперь сделайте text массивом строк: char *text[]; (последняя строка - NULL).

8.6. Сделайте так, чтобы "выскакивающие" окна имели тень. Для этого надо сохранить в
некоторый буфер атрибуты символов (сами символы не надо!), находящихся на местах $:

##########
##########$
##########$
$$$$$$$$$$

а затем прописать этим символам на экране атрибут 0x07 (белый по черному). При стирании
окна (puttext-ом) следует восстановить спасенные атрибуты этих символов (стереть
тень). Если окно имеет размер xlen*ylen, то размер буфера равен xlen+ylen-1 байт.

8.7. Напишите функцию, рисующую на экране прямоугольную рамку. Используйте ее для
рисования рамки окна.

А. Богатырев, 1992-95 - 358 - Си в UNIX

8.8. Напишите "выскакивающее" окно, которое проявляется на экране как бы расширяясь
из точки:

##############
###### ##############
### ###### ##############
###### ##############
##############

Вам следует написать функцию box(x,y,width,height), рисующую цветной прямоугольник с
верхним левым углом (x,y) и размером (width,height). Пусть конечное окно задается
углом (x0,y0) и размером (W,H). Тогда "вырастание" окна описывается таким алгоритмом:

void zoom(int x0, int y0, int W, int H){
int x, y, w, h, hprev; /* промежуточное окно */
for(hprev=0, w=1; w " W; w++){
h = H * w; h /= W; /* W/H == w/h */
if(h == hprev) continue;
hprev = h;
x = x0 + (W - w)/2; /* чтобы центры окон */
y = y0 + (H - h)/2; /* совпадали */
box(x, y, w, h);
delay(10); /* задержка 10 миллисек. */
}
box(x0, y0, W, H);
}

8.9. Составьте библиотеку функций, аналогичных библиотеке curses, для ЭВМ IBM PC в
ОС XENIX. Используйте прямой доступ в видеопамять.

8.10. Напишите рекурсивное решение задачи "ханойские башни" (перекладывание дисков:
есть три стержня, на один из них надеты диски убывающего к вершине диаметра. Требуется
переложить их на третий стержень, никогда не кладя диск большего диаметра поверх
диска меньшего диаметра). Усложнение - используйте пакет curses для изображения
перекладывания дисков на экране терминала. Указание: идея рекурсивного алгоритма:

carry(n, from, to, by) = if( n " 0 ){
carry( n-1, from, by, to );
перенесиОдинДиск( from, to );
carry( n-1, by, to, from );
}
Вызов: carry( n, 0, 1, 2 );
n - сколько дисков перенести (n " 0).
from - откуда (номер стержня).
to - куда.
by - при помощи (промежуточный стержень).

n дисков потребуют (2**n)-1 переносов.

8.11. Напишите программу, ищущую выход из лабиринта ("червяк в лабиринте"). Лабиринт
загружается из файла .maze (не забудьте про расширение табуляций!). Алгоритм
имеет рекурсивную природу и выглядит примерно так:

#include "setjmp.h"
jmp_buf jmp; int found = 0;

maze(){ /* Это головная функция */
if( setjmp(jmp) == 0 ){ /* начало */
if( неСтенка(x_входа, y_входа))
GO( x_входа, y_входа);

А. Богатырев, 1992-95 - 359 - Си в UNIX

}
}
GO(x, y){ /* пойти в точку (x, y) */
if( этоВыход(x, y)){ found = 1; /* нашел выход */
пометить(x, y); longjmp(jmp, 1);}
пометить(x, y);
if( неСтенка(x-1,y)) GO(x-1, y); /* влево */
if( неСтенка(x,y-1)) GO(x, y-1); /* вверх */
if( неСтенка(x+1,y)) GO(x+1, y); /* вправо */
if( неСтенка(x,y+1)) GO(x, y+1); /* вниз */
снятьПометку(x, y);
}
#define пометить(x, y) лабиринт[y][x] = '*'
#define снятьПометку(x, y) лабиринт[y][x] = ' '
#define этоВыход(x, y) (x == x_выхода && y == y_выхода)
/* можно искать "золото": (лабиринт[y][x] == '$') */

неСтенка(x, y){ /* стенку изображайте символом @ или # */
if( координатыВнеПоля(x, y)) return 0; /*край лабиринта*/
return (лабиринт[y][x] == ' ');
}

Отобразите массив лабиринт на видеопамять (или воспользуйтесь curses-ом). Вы увидите
червяка, ползающего по лабиринту в своих исканиях.

8.12. Используя библиотеку termcap напишите функции для:
- очистки экрана.
- позиционирования курсора.
- включения/выключения режима выделения текста инверсией.

8.13. Используя написанные функции, реализуйте программу выбора в меню. Выбранную
строку выделяйте инверсией фона.

/*#!/bin/cc termio.c -O -o termio -ltermcap
* Смотри man termio, termcap и screen.
* Работа с терминалом в стиле System-V.
* Работа с системой команд терминала через /etc/termcap
* Работа со временем.
* Работа с будильником.
*/

#include "stdio.h" /* standard input/output */
#include "sys/types.h" /* system typedefs */
#include "termio.h" /* terminal input/output */
#include "signal.h" /* signals */
#include "fcntl.h" /* file control */
#include "time.h" /* time structure */

void setsigs(), drawItem(), drawTitle(), prSelects(), printTime();

А. Богатырев, 1992-95 - 360 - Си в UNIX

/* Работа с описанием терминала TERMCAP ---------------------------------*/
extern char *getenv (); /* получить переменную окружения */
extern char *tgetstr (); /* получить строчный описатель /termcap/ */
extern char *tgoto (); /* подставить %-параметры /termcap/ */

static char Tbuf[2048], /* буфер для описания терминала, обычно 1024 */
/* Tbuf[] можно сделать локальной автоматической переменной
* в функции tinit(), чтобы не занимать место */
Strings[256], /* буфер для расшифрованных описателей */
*p; /* вспомогательная перем. */
char *tname; /* название типа терминала */
int COLS, /* число колонок экрана */
LINES; /* число строк экрана */
char *CM; /* описатель: cursor motion */
char *CL; /* описатель: clear screen */
char *CE; /* описатель: clear end of line */
char *SO,
*SE; /* описатели: standout Start и End */
char *BOLD,
*NORM; /* описатели: boldface and NoStandout */
int BSflag; /* можно использовать back space '\b' */

void tinit () { /* Функция настройки на систему команд дисплея */
p = Strings;
/* Прочесть описание терминала в Tbuf */
switch (tgetent (Tbuf, tname = getenv ("TERM"))) {
case -1:
printf ("Нет файла TERMCAP (/etc/termcap).\n");
exit (1);
case 0:
printf ("Терминал %s не описан.\n", tname);
exit (2);
case 1:
break; /* OK */
}
COLS = tgetnum ("co"); /* Прочесть числовые описатели. */
LINES = tgetnum ("li");

CM = tgetstr ("cm", &p); /* Прочесть строчные описатели. */
CL = tgetstr ("cl", &p); /* Описатель дешифруется и заносится */
CE = tgetstr ("ce", &p); /* в массив по адресу p. Затем */
SO = tgetstr ("so", &p); /* указатель p продвигается на */
SE = tgetstr ("se", &p); /* свободное место, а адрес расшиф- */
BOLD = tgetstr ("md", &p); /* рованной строки выдается из ф-ции */
NORM = tgetstr ("me", &p);

BSflag = tgetflag( "bs" ); /* Узнать значение флажка:
1 - есть, 0 - нет */
}

А. Богатырев, 1992-95 - 361 - Си в UNIX

/* Макрос, внесенный в функцию.
Дело в том, что tputs в качестве третьего аргумента
требует имя функции, которую она вызывает в цикле: (*f)©;
Если подать на вход макрос, вроде putchar,
а не адрес входа в функцию, мы
и не достигнем желанного эффекта,
и получим ругань от компилятора.
*/
void put © char c;
{ putchar ©; }

/* очистить экран */
void clearScreen () {
if (CL == NULL) /* Функция tputs() дорасшифровывает описатель */
return; /* (обрабатывая задержки) и выдает его */
tputs (CL, 1, put); /* посимвольно ф-цией put© 1 раз */
/* Можно выдать команду не 1 раз, а несколько: например если это */
/* команда сдвига курсора на 1 позицию влево '\b' */
}

/* очистить конец строки, курсор остается на месте */
void clearEOL () { /* clear to the end of line */
if (CE == NULL)
return;
tputs (CE, 1, put);
}

/* позиционировать курсор */
void gotoXY (x, y) { /* y - по вертикали СВЕРХУ-ВНИЗ. */
if (x " 0 || y " 0 || x "= COLS || y "= LINES) {
printf ("Точка (%d,%d) вне экрана\n", x, y);
return;
}
/* CM - описатель, содержащий 2 параметра. Подстановку параметров
* делает функция tgoto() */
tputs (tgoto (CM, x, y), 1, put);
}

/* включить выделение */
void standout () {
if (SO) tputs (SO, 1, put);
}

/* выключить выделение */
void standend () {
if (SE) tputs (SE, 1, put);
/* else normal(); */
}

/* включить жирный шрифт */
void bold () {
if (BOLD) tputs (BOLD, 1, put);
}

А. Богатырев, 1992-95 - 362 - Си в UNIX

/* выключить любой необычный шрифт */
void normal () {
if (NORM) tputs (NORM, 1, put);
else standend();
}

/* Управление драйвером терминала --------------------------------- */

#define ESC '\033'
#define ctrl© ((c) & 037 )

int curMode = 0;
int inited = 0;

struct termio old,
new;
int fdtty;

void ttinit () {
/* открыть терминал в режиме "чтение без ожидания" */
fdtty = open ("/dev/tty", O_RDWR | O_NDELAY);

/* узнать текущие режимы драйвера */
ioctl (fdtty, TCGETA, &old);

new = old;

/* input flags */
/* отменить преобразование кода '\r' в '\n' на вводе */
new.c_iflag &= ~ICRNL;
if ((old.c_cflag & CSIZE) == CS8) /* 8-битный код */
new.c_iflag &= ~ISTRIP; /* отменить & 0177 на вводе */

/* output flags */
/* отменить TAB3 - замену табуляций '\t' на пробелы */
/* отменить ONLCR - замену '\n' на пару '\r\n' на выводе */
new.c_oflag &= ~(TAB3 | ONLCR);

/* local flags */
/* выключить режим ICANON, включить CBREAK */
/* выключить эхоотображение набираемых символов */
new.c_lflag &= ~(ICANON | ECHO);

/* control chars */ /* при вводе с клавиш ждать не более ... */
new.c_cc[VMIN] = 1; /* 1 символа и */
new.c_cc[VTIME] = 0; /* 0 секунд */
/* Это соответствует режиму CBREAK */

/* Символы, нажатие которых заставляет драйвер терминала послать сигнал
* либо отредактировать набранную строку. Значение 0 означает,
* что соответствующего символа не будет */
new.c_cc[VINTR] = ctrl ('C'); /* символ, генерящий SIGINT */
new.c_cc[VQUIT] = '\0'; /* символ, генерящий SIGQUIT */
new.c_cc[VERASE] = '\0'; /* забой (отмена последнего символа)*/
new.c_cc[VKILL] = '\0'; /* символ отмены строки */
/* По умолчанию эти кнопки равны: DEL, CTRL/\, BACKSPACE, CTRL/U */

setsigs ();
inited = 1; /* уже инициализировано */
}

А. Богатырев, 1992-95 - 363 - Си в UNIX

void openVisual () { /* open visual mode (включить "экранный" режим) */
if (!inited)
ttinit ();
if (curMode == 1)
return;

/* установить моды драйвера из структуры new */
ioctl (fdtty, TCSETAW, &new);
curMode = 1; /* экранный режим */
}

void closeVisual () { /* canon mode (включить канонический режим) */
if (!inited)
ttinit ();
if (curMode == 0)
return;

ioctl (fdtty, TCSETAW, &old);
curMode = 0; /* канонический режим */
}

/* завершить процесс */
void die (nsig) {
normal();
closeVisual (); /* При завершении программы (в том числе по
* сигналу) мы должны восстановить прежние режимы драйвера,
* чтобы терминал оказался в корректном состоянии. */
gotoXY (0, LINES - 1);
putchar ('\n');
if (nsig)
printf ("Пришел сигнал #%d\n", nsig);
exit (nsig);
}

void setsigs () {
register ns;

/* Перехватывать все сигналы; завершаться по ним. */
/* UNIX имеет 15 стандартных сигналов. */
for (ns = 1; ns "= 15; ns++)
signal (ns, die);
}

А. Богатырев, 1992-95 - 364 - Си в UNIX

/* Работа с меню -------------------------------------------- */

struct menu {
char *m_text; /* выдаваемая строка */
int m_label; /* помечена ли она ? */
} menuText[] = {
/* названия песен Beatles */
{ "Across the Universe", 0 } ,
{ "All I've got to do", 0 } ,
{ "All my loving", 0 } ,
{ "All together now", 0 } ,
{ "All You need is love",0 } ,
{ "And I love her", 0 } ,
{ "And your bird can sing", 0 } ,
{ "Another girl", 0 } ,
{ "Any time at all", 0 } ,
{ "Ask me why", 0 } ,
{ NULL, 0 }
};

#define Y_TOP 6
int nitems; /* количество строк в меню */
int nselected = 0; /* количество выбранных строк */

char title[] =
"ПРОБЕЛ - вниз, ЗАБОЙ - вверх, ESC - выход, \
ENTER - выбрать, TAB - отменить";

# define TIMELINE 1

void main (ac, av) char **av; {
char **line;
register i;
int c;
int n; /* текущая строка */
extern char readkey (); /* forward */

extern char *ttyname (); /* имя терминала */
char *mytty;

extern char *getlogin (); /* имя пользователя */
char *userName = getlogin ();

srand (getpid () + getuid ()); /* инициализировать
* датчик случайных чисел */
/* считаем строки меню */
for (nitems = 0; menuText[nitems].m_text != NULL; nitems++);

/* инициализируем терминал */
tinit (); ttinit();
mytty = ttyname(fdtty);
openVisual ();

А. Богатырев, 1992-95 - 365 - Си в UNIX

again:
clearScreen ();
if (mytty != NULL && userName != NULL) {
gotoXY (0, TIMELINE);
bold ();
printf ("%s", userName);
normal ();
printf (" at %s (%s)", mytty, tname);
}

drawTitle ("", Y_TOP - 4);
drawTitle (title, Y_TOP - 3);
drawTitle ("", Y_TOP - 2);

/* рисуем меню */
for (i = 0; i " nitems; i++) {
drawItem (i, 20, Y_TOP + i, 0);
}

/* цикл перемещений по меню */
for (n=0; ; ) {
printTime (); /* выдаем текущее время */
drawItem (n, 20, Y_TOP + n, 1);

c = getcharacter ();

drawItem (n, 20, Y_TOP + n, 0);

switch © {
case ' ':
go_down:
n++;
if (n == nitems)
n = 0;
break;

case '\b': case 0177:
n--;
if (n " 0)
n = nitems - 1;
break;

case ESC:
goto out;

case '\t': /* Unselect item */
if (menuText[n].m_label != 0) {
menuText[n].m_label = 0;
drawItem (n, 20, Y_TOP + n, 0);
nselected--;
prSelects ();
}
goto go_down;

А. Богатырев, 1992-95 - 366 - Си в UNIX

case '\r': /* Select item */
case '\n':
bold ();
drawTitle (menuText[n].m_text, LINES - 2);
/* last but two line */
normal ();

if (menuText[n].m_label == 0) {
menuText[n].m_label = 1;
drawItem (n, 20, Y_TOP + n, 0);
nselected++;
prSelects ();
}
goto go_down;

default:
goto go_down;
}
}

out:
clearScreen ();

gotoXY (COLS / 3, LINES / 2);
bold ();
printf ("Нажми любую кнопку.");
normal ();

/* замусорить экран */
while (!(c = readkey ())) {
/* случайные точки */
gotoXY (rand () % (COLS - 1), rand () % LINES);
putchar ("@.*"[rand () % 3]); /* выдать символ */
fflush (stdout);
}

standout ();
printf ("Нажата кнопка с кодом 0%o\n", c & 0377);
standend ();

if (c == ESC) {
sleep (2); /* подождать 2 секунды */
goto again;
}

die (0); /* успешно завершиться,
* восстановив режимы драйвера */
}

А. Богатырев, 1992-95 - 367 - Си в UNIX

/* Нарисовать строку меню номер i
* в координатах (x,y) с или без выделения
*/
void drawItem (i, x, y, out) {
gotoXY (x, y);
if (out) {
standout ();
bold ();
}
printf ("%c %s ",
menuText[i].m_label ? '-' : ' ', /* помечено или нет */
menuText[i].m_text /* сама строка */
);

if (out) {
standend ();
normal ();
}
}

/* нарисовать центрированную строку в инверсном изображении */
void drawTitle (title, y) char *title; {
register int n;
int length = strlen (title); /* длина строки */

gotoXY (0, y);
/* clearEOL(); */
standout ();

for (n = 0; n " (COLS - length) / 2; n++)
putchar (' ');

printf ("%s", title); n += length;

/* дорисовать инверсией до конца экрана */
for (; n " COLS - 1; n++)

Список страниц

Закладка в соц.сетях

Купить

☏ Заказ рекламы: +3805044-68-872

© Ассоциация электронных библиотек Украины

☝ Все материалы сайта (включая статьи, изображения, рекламные объявления и пр.) предназначены только для предварительного ознакомления. Все права на публикации, представленные на сайте принадлежат их законным владельцам. Просим Вас не сохранять копии информации.