Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103121373
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-04-16 17:30:51

总看到有人发帖子问那个通用菜单程序中的几个错误不能编译的事,回去找了一下我修改后可以正常工作的程序,现贴出来,大家共享一下吧。 
我的系统是scounix的。 
编译 cc menu.c -o menu -lcurses 
代码: 
/************************************************************** 
本程序需要借肋两个参数文件来实现: 
(1)、对菜单中每一项参数进行说明的文件(menu.def),它格式如下所述: 
!所属菜单代号!项顺序号!菜单项名称!外挂程序名称!下级菜单代号! 
说明: 
1、如菜单代号为"0",则表示此项属于主菜单; 
2、如外挂程序名称为"0",则表示此菜单项对应的过程在菜单程序内部或对应于一个子菜单; 
3、如下级菜单代号为"0",则表示此菜单项无下级子菜单; 
4、项顺序号同时可作为菜单热键使用。 
假如文件menu.def中有下面这一行: 
!0!3!格式化磁盘!format /dev/rfd0135ds18!0! 
它表示主菜单的第三项为格式化磁盘,它对应的执行过程为 format /dev/rfd0135ds18,本项无子菜单。 
如果用户想把自己编的实现查询功能程序XXX挂到本程序主菜单第4项上,则可在menu.def中增加下面 
这一行: 
!0!4!查询!XXX!0! 
(2)、对各菜单参数进行说明文件(menu.conf),其格式如下所述: 
!菜单代号!上一级菜单代号!边框标志!菜单宽度!菜单行数!菜单列数!起始横坐标!起始纵坐标! 
说明: 
1、边框标志为"0"表示无框,为"1"表示有边框; 
2、上级菜单代号为"-1",表示无上级菜单; 
3、如菜单代号为"0",表示主菜单。 
当用户对菜单显示样式不满意时,可通过调整此文件设计个性化的界面 
***************************************************************/ 
#include  
#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; 

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) { 
      printw( "\n不能打开菜单定义文件\n"); 
      refresh(); 
      endwin(); 
      exit(-1); 
   } 
   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; 
   int  ch; 

   this = head; 
   disponepage(this); 
   curpos = curp; 
   scrpos = curscrp; 
   lastcurpos = lastscrcurpos = 0; 
   revcurpos(); 
   for(;;) { 
   ch=wgetch(curw); 
      switch (ch) { 
      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++){ 
            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++){ 
            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      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; 
         } 
      } 
   } 

/* 显示上一行函数 */ 
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) { 
      printw( "can not open menu config file"); 
      refresh(); 
      endwin(); 
      exit(-1); 
   } 
   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; 
         } 
      } 
   } 

/* 初始化资源*/ 
void initial() /* 自定开启 curses 函式 */  

   initscr(); 
   cbreak(); 
   nonl(); 
   noecho(); 
   intrflush(stdscr,FALSE); 
   keypad(stdscr,TRUE); 
   refresh(); 

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

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

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

   def_prog_mode();    
        //system("clear"); 
   //fprintf(stderr, "%s: \n", scrpos->item); 
   system(scrpos->prog); 
   reset_prog_mode(); 
   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); 

阅读(164) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~