在Unix下用C编写curses程序的一些常用模块

本文转载自 chinaunix

初始化资源

    
void initial() /* 自定开启 curses 函式 */  

{  

    initscr();  

    cbreak(); nonl(); noecho();  

    intrflush(stdscr,FALSE);  

    keypad(stdscr,TRUE);  

    refresh();  

}  





/* 按键等待函数 */  
    
void keycont()  

{  

    fprintf(stderr, "按键继续..."); getchar();  

}  





/* 运行可执行程序函数 */  
    
void execprog()  

{  

    system("clear");  

    fprintf(stderr, "%s: \n", scrpos->;item);  

    system(scrpos->;prog);  

    keycont(); initial();  

    touchwin(boxwin); touchwin(curw); keypad(curw, TRUE);  

    wrefresh(boxwin); wrefresh(curw);  

}  





/* 清除窗口函数 */  
    
void clearwin()  

{  

    wmove(boxwin, 0, 0);  

    wclrtobot(boxwin); wrefresh(boxwin); delwin(curw); delwin(boxwin);  

}  






/* 主函数 */  

    
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();  

}  





/* 取菜单各项参数函数 */  

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, "\n不能打开菜单定义文件\n");  

	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);  

}  







/* 菜单处理函数 */  

    
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<m_conf.m_col;i++){//无双修改i/td>;  

		    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<m_conf.m_col;i++){//无双修改i/td>;  

		    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;  

	}  

    }  

}  







/* 反显当前项函数 */  
    
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);  

}  





/* 正常显示上一项函数 */  
    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);  

    }  





/* 显示一页函数 */  
    
void disponepage(first)  

    struct menu *first;  

{  

    short col, row;  



    begin=first; /* begin 为本页首指针 */  

    for(row=0;row<m_conf.m_lengh ;row++){//无双修改row/td>;  

	//这两个地方都不是很清楚,我想这个函数是想打印菜单的,所以照这个意思写

	for(col=0;col<m_conf.m_col;col++){//无双修改 col/td>;  

	    /* 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;  

	    }  

	}  

    }  

}  







/* 显示上一行函数 */  
    
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);  

}  





/* 显示下一行函数 */  
    
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;  

    }  

}  







/* 取指定菜单参数函数 */  
    
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 ;  

}  






/* 取指定菜单参数处理函数 */  
    
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 == '!' ) {  

	    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;  

	    }  

	}  

    }  

}  




/* 取指定项参数处理函数 */  
    

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 == '!' ) {  

	    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;  

	    }  

	}  

    }  

}  





数据结构和头文件等初始化信息

#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;  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值