在Unix下用C编写curses程序的一些常用模块(转)[@more@]
总有人问这个问题,下面是整理的模块代码,可以作为编程的参考demo。
几个部分可以连接起来编译程可执行程序运行。
初始化资源
[code:1:b2615b2355]
void initial() /* 自定开启 curses 函式 */
{
initscr();
cbreak(); nonl(); noecho();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}
[/code:1:b2615b2355]
/* 按键等待函数 */
[code:1:b2615b2355]
void keycont()
{
fprintf(stderr, "按键继续..."); getchar();
}
[/code:1:b2615b2355]
/* 运行可执行程序函数 */
[code:1:b2615b2355]
void execprog()
{
system("clear");
fprintf(stderr, "%s:
", scrpos->item);
system(scrpos->prog);
keycont(); initial();
touchwin(boxwin); touchwin(curw); keypad(curw, TRUE);
wrefresh(boxwin); wrefresh(curw);
}
[/code:1:b2615b2355]
/* 清除窗口函数 */
[code:1:b2615b2355]
void clearwin()
{
wmove(boxwin, 0, 0);
wclrtobot(boxwin); wrefresh(boxwin); delwin(curw); delwin(boxwin);
}
[/code:1:b2615b2355]
/* 主函数 */
[code:1:b2615b2355]
main()
{
initial();
getmenuconf(0); /* 取第0号菜单参数 */
/* 创建主窗口 */
menuwin=newwin(m_conf.m_lengh, m_conf.m_wight, m_conf.m_bx+1, m_conf.m_by+1);
curw=menuwin; lastw[wno]=menuwin;
getitem(); /* 取当前菜单各项内容 */
domenu(head, 0);
endwin();
}
[/code:1:b2615b2355]
/* 取菜单各项参数函数 */
[code:1:b2615b2355]
void getitem()
{
FILE *fp;
char buff[0x100];
/* 建边框窗口 */
boxwin=newwin(m_conf.m_lengh+2,m_conf.m_wight+2,m_conf.m_bx,m_conf.m_by);
keypad(curw, TRUE);
if (m_conf.bord_flag==1) {
box(boxwin, 0,0 );
wrefresh(boxwin);
}
head=NULL;
if ((fp = fopen("./menu.def","r")) == NULL) {
fprintf(stderr, "
不能打开菜单定义文件
");
return;
}
while( fgets(buff, 0x100, fp)!=NULL) {
get_m_item(buff);
if (m_item.menu_code != menu_no)
continue;
new=(struct menu*)malloc(sizeof(struct menu));
if (head == NULL) {
last = head; head = new;
}
else {
this->next = new; last = this;
}
this = new;
this->menu_code=m_item.menu_code;
this->item_order=m_item.item_order;
strcpy(this->item,m_item.item);
strcpy(this->prog,m_item.prog);
this->submenu_code=m_item.submenu_code;
this->next=NULL;
this->prev = last;
}
fclose(fp);
}
[/code:1:b2615b2355]
/* 菜单处理函数 */
[code:1:b2615b2355]
void domenu(curscrp, curp)
struct menu *curscrp;
int curp;
{
int i, x, y;
struct menu *mpos;
this = head;
disponepage(this);
curpos = curp; scrpos = curscrp;
lastcurpos = lastscrcurpos = 0;
revcurpos();
for(;;) {
switch (wgetch(curw)) {
case ENT:
/* 有下一级菜单 */
if ((!strcmp(scrpos->prog, "0")) && (scrpos->submenu_code != 0)) {
lastbegin = begin->next;
getmenuconf(scrpos->submenu_code);
menu_no = scrpos->submenu_code;
wno++;
lastmenucur[wno]=curpos;
lastscr[wno] = scrpos;
lastw[wno]=curw;
workwin=newwin(m_conf.m_lengh,m_conf.m_wight,m_conf.m_bx+1,m_conf.m_by+1);
curw=workwin;
getitem();
domenu(head, 0);
}
/* 是内部函数 */
/* 是外部可执行程序 */
else {
endwin();
execprog();
}
break;
case ESC:
case 'q':
case 'Q':
case '0':
/* 无上级菜单 */
if (m_conf.last_code == -1) {
clearwin(); endwin(); exit(0);
}
/* 有上级菜单 */
else {
menu_no = m_conf.last_code;
clearwin();
getmenuconf(menu_no);
getitem();
touchwin(lastw[wno]);
curw=lastw[wno];
curpos = lastmenucur[wno];
scrpos = lastscr[wno];
wno--;
wrefresh(curw);
}
break;
case 'r':
case 'R':
case REFRESH: /* 重显屏幕 */
wrefresh(curscr);
break;
case KEY_RIGHT: /* 右光标键 */
if ( scrpos->next != NULL ) {
lastcurpos = curpos; lastscrpos = scrpos;
scrpos=scrpos->next;
getyx(curw, x, y);
if((x==m_conf.m_lengh-1)&&(curpos%m_conf.m_col==m_conf.m_col-1)){
curpos-=(m_conf.m_col-1); lastcurpos = curpos - 1;
/* 实现向上卷屏 */
wmove(curw, 0, 0); wdeleteln(curw); dispnextline("R");
}
else
curpos++;
if ((curpos%m_conf.m_col == 0) && (m_conf.m_lengh == 1)) {
revcurpos(); break;
}
else {
nomlastpos(); revcurpos();
}
}
break;
case KEY_LEFT: /* 左光标键 */
if ( scrpos->prev != NULL ) {
lastcurpos = curpos; lastscrpos = scrpos;
scrpos=scrpos->prev;
getyx(curw, x, y);
if ((x==0) && (curpos%m_conf.m_col ==0)) {
curpos+=m_conf.m_col-1; lastcurpos = curpos + 1;
/* 实现向下卷屏 */
winsertln(curw); dispprevline("L");
}
else
curpos--;
if ((curpos%m_conf.m_col==m_conf.m_col-1)&&(m_conf.m_lengh==1)) {
revcurpos(); break;
}
else {
nomlastpos(); revcurpos();
}
}
break;
case KEY_UP: /* 上光标键 */
lastcurpos = curpos; lastscrpos = scrpos;
mpos = scrpos;
for(i=0; i
if ( mpos->prev != NULL ) mpos=mpos->prev; else break; } if ( i==m_conf.m_col ) { getyx(curw, x, y); if (x==0) { lastcurpos += m_conf.m_col; /* 实现向下卷屏 */ winsertln(curw); dispprevline("U"); } else { curpos-=m_conf.m_col; } scrpos = mpos; if ( m_conf.m_lengh!=1) nomlastpos(); revcurpos(); } break; case KEY_DOWN: /* 下光标键 */ lastcurpos = curpos; lastscrpos = scrpos; mpos = scrpos; for(i=0;i if ( mpos->next != NULL ) mpos=mpos->next; else break; } if ( i==m_conf.m_col ) { getyx(curw, x, y); if (x==m_conf.m_lengh-1) { lastcurpos -= m_conf.m_col; /* 实现向上卷屏 */ wmove(curw, 0, 0); wdeleteln(curw); dispnextline("D"); } else curpos+=m_conf.m_col; scrpos = mpos; if ( m_conf.m_lengh!=1) nomlastpos(); revcurpos(); } break; default: beep(); break; } } } [/code:1:b2615b2355]/* 反显当前项函数 */ [code:1:b2615b2355]void revcurpos() { wattrset(curw, A_STANDOUT); wmove(curw, curpos/m_conf.m_col, (curpos%m_conf.m_col)*m_conf.m_wight/m_conf.m_col+m_conf.m_col); wprintw(curw, "%s", scrpos->item); wattrset(curw, A_NORMAL); wrefresh(boxwin); } [/code:1:b2615b2355]/* 正常显示上一项函数 */ [code:1:b2615b2355]void nomlastpos() { wmove(curw, lastcurpos/m_conf.m_col, (lastcurpos%m_conf.m_col) *m_conf.m_wight/m_conf.m_col+m_conf.m_col); wprintw(curw, "%s", lastscrpos->item); } [/code:1:b2615b2355]/* 显示一页函数 */ [code:1:b2615b2355]void disponepage(first) struct menu *first; { short col, row; begin=first; /* begin 为本页首指针 */ for(row=0;row //这两个地方都不是很清楚,我想这个函数是想打印菜单的,所以照这个意思写for(col=0;col /* m_conf.m_wight/m_col为每一菜单项应占列数*/ wmove(curw,row,col*m_conf.m_wight/m_conf.m_col+m_conf.m_col); wprintw(curw, "%s", first->item); wrefresh(curw); last = first; first = first->next; if (first == NULL) { break; } } } } [/code:1:b2615b2355]/* 显示上一行函数 */ [code:1:b2615b2355]void dispprevline(flag) char flag[2]; /* L-左光标引起 U-上光标引起 */ { struct menu *tmppos; int tmpcurpos; tmpcurpos = curpos; tmppos = scrpos; if ( flag[0] == 'U') { while ( tmpcurpos % m_conf.m_col != 0) { tmppos = tmppos->prev; tmpcurpos--; } tmppos = tmppos->prev; } for (tmpcurpos = m_conf.m_col-1; tmpcurpos >= 0; tmpcurpos--) { wmove(curw, 0, (tmpcurpos%m_conf.m_col) *m_conf.m_wight/m_conf.m_col+m_conf.m_col); wprintw(curw, "%s", tmppos->item); begin = tmppos; /*begin 为本页首指针*/ last = tmppos; tmppos = tmppos->prev; if (tmppos == NULL) break; } wrefresh(curw); } [/code:1:b2615b2355]/* 显示下一行函数 */ [code:1:b2615b2355]void dispnextline(flag) char flag[2];/* R-右光标引起 D-下光标引起 */ { struct menu *tmppos; int tmpcurpos; tmpcurpos = curpos; tmppos = scrpos; if ( flag[0] == 'D') { while ( tmpcurpos % m_conf.m_col != m_conf.m_col-1) { tmppos = tmppos->next; tmpcurpos++; } tmppos = tmppos->next; } for (tmpcurpos = 0; tmpcurpos < m_conf.m_col; tmpcurpos++) { wmove(curw, m_conf.m_lengh-1, (tmpcurpos%m_conf.m_col) *m_conf.m_wight/m_conf.m_col+m_conf.m_col); wprintw(curw, "%s", tmppos->item); last=tmppos;/* last 为本页最后一个结点指针 */ begin=tmppos; tmppos = tmppos->next; if (tmppos == NULL) break; } } [/code:1:b2615b2355]/* 取指定菜单参数函数 */ [code:1:b2615b2355]void getmenuconf(menu_code) short menu_code; { FILE *fp; char menu_buff[0x100]; if ((fp = fopen("menu.conf", "r"))==NULL) { fprintf(stderr, "can not open menu config file"); return; } while( fgets(menu_buff, 0x100, fp)!=NULL ) { get_m_conf(menu_buff); if (m_conf.menu_code == menu_code) break; } return ; } [/code:1:b2615b2355]/* 取指定菜单参数处理函数 */ [code:1:b2615b2355]void get_m_conf(menu_conf) char *menu_conf; { register i, j, k; char buff[20]; j = k = 0; for (i = 0; i < strlen(menu_conf); i++) { if ( menu_conf[i] == '!' ) { j++; if ( j == 1) { k = i+1; continue; } switch(j) { case 2: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.menu_code = atoi(buff); k=i+1; break; case 3: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.last_code = atoi(buff); k=i+1; break; case 4: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.bord_flag = atoi(buff); k=i+1; break; case 5: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.m_wight = atoi(buff); k=i+1; break; case 6: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.m_lengh = atoi(buff); k=i+1; break; case 7: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.m_col = atoi(buff); k=i+1; break; case 8: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.m_bx = atoi(buff); k=i+1; break; case 9: memcpy(buff, &menu_conf[k], i-k); buff[i-k]=0; m_conf.m_by = atoi(buff); k=i+1; break; default: break; } } } } [/code:1:b2615b2355]/* 取指定项参数处理函数 */ [code:1:b2615b2355]void get_m_item(menu_item) char *menu_item; { register i, j, k; char buff[80]; j = k = 0; for (i = 0; i < strlen(menu_item); i++) { if ( menu_item[i] == '!' ) { j++; if ( j == 1) { k = i+1; continue; } switch(j) { case 2: memcpy(buff, &menu_item[k], i-k); buff[i-k] = 0; m_item.menu_code = atoi(buff); k=i+1; break; case 3: memcpy(buff, &menu_item[k], i-k); buff[i-k] = 0; m_item.item_order = atoi(buff); k=i+1; break; case 4: memcpy(buff, &menu_item[k], i-k); buff[i-k] = 0; strcpy(m_item.item,buff); k=i+1; break; case 5: memcpy(buff, &menu_item[k], i-k); buff[i-k] = 0; strcpy(m_item.prog,buff); k=i+1; break; case 6: memcpy(buff, &menu_item[k], i-k); buff[i-k] = 0; m_item.submenu_code = atoi(buff); k=i+1; break; default: break; } } } } [/code:1:b2615b2355]数据结构和头文件等初始化信息[code:1:b2615b2355]#include #define ESC 27 #define ENT 13 #define REFRESH 12 #define MAX_M 10 /* 菜单最大层数 */ void initial(),nomlastpos(),revcurpos(),disponepage(),dispprevline(); void dispnextline(),domenu(),getmenuconf(),keycont(); void getitem(), get_m_conf(), get_m_item(),clearwin(),execprog(); /* 标识每一菜单项的结构 */ struct menu { short menu_code; /* 所属菜单代号 */ short item_order; /* 项顺序号 */ char item[20]; /* 菜单项名称 */ char prog[80]; /* 本项菜单执行程序 */ short submenu_code; /* 下一级菜单编号 */ struct menu *next; /* 指向上一项的指针 */ struct menu *prev; /* 指向下一项的指针 */ } m_item,*head,*this,*new,*last,*scrpos,*lastscrpos,*begin,*lastbegin,*lastscr[MAX_M]; /* 标识每一菜单内容的结构 */ struct menuconf { short menu_code; /* 菜单代号 */ short last_code; /* 上一级菜单代号 */ short bord_flag; /* 边框标志 0--无边框 1--有边框 **/ short m_wight; /* 菜单显示宽度 */ short m_lengh; /* 每一行项数 */ short m_col; /* 菜单列数 */ short m_bx; /* 菜单起始横坐标 */ short m_by; /* 菜单起始纵坐标 */ } m_conf; WINDOW *menuwin, *boxwin, *curw, *lastw[MAX_M], *workwin; long curpos, lastcurpos, lastscrcurpos, lastmenucur[MAX_M]; short menu_no = 0, wno = 0;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8225414/viewspace-944576/
,如需转载,请注明出处,否则将追究法律责任。