?? 在unix下用c編寫curses程序的一些常用模塊.htm
字號:
<tr><td valign=top><br> 總有人問這個問題,下面是整理的模塊代碼,可以作為編程的參考demo。
<br>
<br>幾個部分可以連接起來編譯程可執行程序運行。
<br>
<br>初始化資源
<br> [code:1:b2615b2355]
<br>void initial() /* 自定開啟 curses 函式 */
<br>{
<br> initscr();
<br> cbreak(); nonl(); noecho();
<br> intrflush(stdscr,FALSE);
<br> keypad(stdscr,TRUE);
<br> refresh();
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 按鍵等待函數 */
<br> [code:1:b2615b2355]
<br>void keycont()
<br>{
<br> fprintf(stderr, "按鍵繼續..."); getchar();
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 運行可執行程序函數 */
<br> [code:1:b2615b2355]
<br>void execprog()
<br>{
<br> system("clear");
<br> fprintf(stderr, "%s: \n", scrpos->item);
<br> system(scrpos->prog);
<br> keycont(); initial();
<br> touchwin(boxwin); touchwin(curw); keypad(curw, TRUE);
<br> wrefresh(boxwin); wrefresh(curw);
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 清除窗口函數 */
<br> [code:1:b2615b2355]
<br>void clearwin()
<br>{
<br> wmove(boxwin, 0, 0);
<br> wclrtobot(boxwin); wrefresh(boxwin); delwin(curw); delwin(boxwin);
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>
<br>/* 主函數 */
<br>
<br> [code:1:b2615b2355]
<br>main()
<br>{
<br> initial();
<br> getmenuconf(0); /* 取第0號菜單參數 */
<br>
<br> /* 創建主窗口 */
<br> menuwin=newwin(m_conf.m_lengh, m_conf.m_wight, m_conf.m_bx+1, m_conf.m_by+1);
<br> curw=menuwin; lastw[wno]=menuwin;
<br>
<br> getitem(); /* 取當前菜單各項內容 */
<br> domenu(head, 0);
<br> endwin();
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 取菜單各項參數函數 */
<br>
<br>[code:1:b2615b2355]
<br>
<br>void getitem()
<br>{
<br> FILE *fp;
<br> char buff[0x100];
<br>
<br> /* 建邊框窗口 */
<br> boxwin=newwin(m_conf.m_lengh+2,m_conf.m_wight+2,m_conf.m_bx,m_conf.m_by);
<br> keypad(curw, TRUE);
<br> if (m_conf.bord_flag==1) {
<br> box(boxwin, 0,0 );
<br> wrefresh(boxwin);
<br> }
<br>
<br> head=NULL;
<br> if ((fp = fopen("./menu.def","r")) == NULL) {
<br> fprintf(stderr, "\n不能打開菜單定義文件\n");
<br> return;
<br> }
<br> while( fgets(buff, 0x100, fp)!=NULL) {
<br> get_m_item(buff);
<br>
<br> if (m_item.menu_code != menu_no)
<br> continue;
<br>
<br> new=(struct menu*)malloc(sizeof(struct menu));
<br> if (head == NULL) {
<br> last = head; head = new;
<br> }
<br> else {
<br> this->next = new; last = this;
<br> }
<br> this = new;
<br> this->menu_code=m_item.menu_code;
<br> this->item_order=m_item.item_order;
<br> strcpy(this->item,m_item.item);
<br> strcpy(this->prog,m_item.prog);
<br> this->submenu_code=m_item.submenu_code;
<br> this->next=NULL;
<br> this->prev = last;
<br> }
<br> fclose(fp);
<br>}
<br>
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 菜單處理函數 */
<br>
<br> [code:1:b2615b2355]
<br>void domenu(curscrp, curp)
<br> struct menu *curscrp;
<br> int curp;
<br>{
<br> int i, x, y;
<br> struct menu *mpos;
<br>
<br> this = head;
<br> disponepage(this);
<br> curpos = curp; scrpos = curscrp;
<br> lastcurpos = lastscrcurpos = 0;
<br> revcurpos();
<br> for(;;) {
<br> switch (wgetch(curw)) {
<br> case ENT:
<br> /* 有下一級菜單 */
<br> if ((!strcmp(scrpos->prog, "0")) && (scrpos->submenu_code != 0)) {
<br> lastbegin = begin->next;
<br> getmenuconf(scrpos->submenu_code);
<br> menu_no = scrpos->submenu_code;
<br>
<br> wno++;
<br> lastmenucur[wno]=curpos;
<br> lastscr[wno] = scrpos;
<br> lastw[wno]=curw;
<br>
<br> workwin=newwin(m_conf.m_lengh,m_conf.m_wight,m_conf.m_bx+1,m_conf.m_by+1);
<br> curw=workwin;
<br> getitem();
<br> domenu(head, 0);
<br> }
<br> /* 是內部函數 */
<br> /* 是外部可執行程序 */
<br> else {
<br> endwin();
<br> execprog();
<br> }
<br> break;
<br> case ESC:
<br> case 'q':
<br> case 'Q':
<br> case '0':
<br> /* 無上級菜單 */
<br> if (m_conf.last_code == -1) {
<br> clearwin(); endwin(); exit(0);
<br> }
<br> /* 有上級菜單 */
<br> else {
<br> menu_no = m_conf.last_code;
<br> clearwin();
<br> getmenuconf(menu_no);
<br> getitem();
<br> touchwin(lastw[wno]);
<br> curw=lastw[wno];
<br> curpos = lastmenucur[wno];
<br> scrpos = lastscr[wno];
<br> wno--;
<br> wrefresh(curw);
<br> }
<br> break;
<br> case 'r':
<br> case 'R':
<br> case REFRESH: /* 重顯屏幕 */
<br> wrefresh(curscr);
<br> break;
<br> case KEY_RIGHT: /* 右光標鍵 */
<br> if ( scrpos->next != NULL ) {
<br> lastcurpos = curpos; lastscrpos = scrpos;
<br> scrpos=scrpos->next;
<br> getyx(curw, x, y);
<br> if((x==m_conf.m_lengh-1)&&(curpos%m_conf.m_col==m_conf.m_col-1)){
<br> curpos-=(m_conf.m_col-1); lastcurpos = curpos - 1;
<br> /* 實現向上卷屏 */
<br> wmove(curw, 0, 0); wdeleteln(curw); dispnextline("R");
<br> }
<br> else
<br> curpos++;
<br> if ((curpos%m_conf.m_col == 0) && (m_conf.m_lengh == 1)) {
<br> revcurpos(); break;
<br> }
<br> else {
<br> nomlastpos(); revcurpos();
<br> }
<br> }
<br> break;
<br> case KEY_LEFT: /* 左光標鍵 */
<br> if ( scrpos->prev != NULL ) {
<br> lastcurpos = curpos; lastscrpos = scrpos;
<br> scrpos=scrpos->prev;
<br> getyx(curw, x, y);
<br> if ((x==0) && (curpos%m_conf.m_col ==0)) {
<br> curpos+=m_conf.m_col-1; lastcurpos = curpos + 1;
<br> /* 實現向下卷屏 */
<br> winsertln(curw); dispprevline("L");
<br> }
<br> else
<br> curpos--;
<br> if ((curpos%m_conf.m_col==m_conf.m_col-1)&&(m_conf.m_lengh==1)) {
<br> revcurpos(); break;
<br> }
<br> else {
<br> nomlastpos(); revcurpos();
<br> }
<br> }
<br> break;
<br> case KEY_UP: /* 上光標鍵 */
<br> lastcurpos = curpos; lastscrpos = scrpos;
<br> mpos = scrpos;
<br> for(i=0; i<m_conf.m_col;i++){//無雙修改i/td>
<br> if ( mpos->prev != NULL ) mpos=mpos->prev;
<br> else break;
<br> }
<br> if ( i==m_conf.m_col ) {
<br> getyx(curw, x, y);
<br> if (x==0) {
<br> lastcurpos += m_conf.m_col;
<br> /* 實現向下卷屏 */
<br> winsertln(curw); dispprevline("U");
<br> }
<br> else {
<br> curpos-=m_conf.m_col;
<br> }
<br> scrpos = mpos;
<br> if ( m_conf.m_lengh!=1)
<br> nomlastpos();
<br> revcurpos();
<br> }
<br> break;
<br> case KEY_DOWN: /* 下光標鍵 */
<br> lastcurpos = curpos; lastscrpos = scrpos;
<br> mpos = scrpos;
<br> for(i=0;i<m_conf.m_col;i++){//無雙修改i/td>
<br> if ( mpos->next != NULL )
<br> mpos=mpos->next;
<br> else
<br> break;
<br> }
<br> if ( i==m_conf.m_col ) {
<br> getyx(curw, x, y);
<br> if (x==m_conf.m_lengh-1) {
<br> lastcurpos -= m_conf.m_col;
<br> /* 實現向上卷屏 */
<br> wmove(curw, 0, 0); wdeleteln(curw); dispnextline("D");
<br> }
<br> else
<br> curpos+=m_conf.m_col;
<br> scrpos = mpos;
<br> if ( m_conf.m_lengh!=1)
<br> nomlastpos();
<br> revcurpos();
<br> }
<br> break;
<br> default:
<br> beep();
<br> break;
<br> }
<br> }
<br>}
<br>
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 反顯當前項函數 */
<br> [code:1:b2615b2355]
<br>void revcurpos()
<br>{
<br> wattrset(curw, A_STANDOUT);
<br> wmove(curw, curpos/m_conf.m_col,
<br> (curpos%m_conf.m_col)*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
<br> wprintw(curw, "%s", scrpos->item);
<br> wattrset(curw, A_NORMAL);
<br> wrefresh(boxwin);
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 正常顯示上一項函數 */
<br>[code:1:b2615b2355]
<br> void nomlastpos() {
<br> wmove(curw, lastcurpos/m_conf.m_col, (lastcurpos%m_conf.m_col)
<br> *m_conf.m_wight/m_conf.m_col+m_conf.m_col);
<br> wprintw(curw, "%s", lastscrpos->item);
<br> }
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 顯示一頁函數 */
<br> [code:1:b2615b2355]
<br>void disponepage(first)
<br> struct menu *first;
<br>{
<br> short col, row;
<br>
<br> begin=first; /* begin 為本頁首指針 */
<br> for(row=0;row<m_conf.m_lengh ;row++){//無雙修改row/td>
<br> //這兩個地方都不是很清楚,我想這個函數是想打印菜單的,所以照這個意思寫
<br> for(col=0;col<m_conf.m_col;col++){//無雙修改 col/td>
<br> /* m_conf.m_wight/m_col為每一菜單項應占列數*/
<br> wmove(curw,row,col*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
<br> wprintw(curw, "%s", first->item);
<br> wrefresh(curw);
<br> last = first;
<br> first = first->next;
<br> if (first == NULL) {
<br> break;
<br> }
<br> }
<br> }
<br>}
<br>
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 顯示上一行函數 */
<br> [code:1:b2615b2355]
<br>void dispprevline(flag)
<br> char flag[2]; /* L-左光標引起 U-上光標引起 */
<br>{
<br> struct menu *tmppos;
<br> int tmpcurpos;
<br>
<br> tmpcurpos = curpos;
<br> tmppos = scrpos;
<br> if ( flag[0] == 'U') {
<br> while ( tmpcurpos % m_conf.m_col != 0) {
<br> tmppos = tmppos->prev;
<br> tmpcurpos--;
<br> }
<br> tmppos = tmppos->prev;
<br> }
<br> for (tmpcurpos = m_conf.m_col-1; tmpcurpos >= 0; tmpcurpos--) {
<br> wmove(curw, 0, (tmpcurpos%m_conf.m_col)
<br> *m_conf.m_wight/m_conf.m_col+m_conf.m_col);
<br> wprintw(curw, "%s", tmppos->item);
<br> begin = tmppos; /*begin 為本頁首指針*/
<br> last = tmppos;
<br> tmppos = tmppos->prev;
<br> if (tmppos == NULL)
<br> break;
<br> }
<br> wrefresh(curw);
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 顯示下一行函數 */
<br> [code:1:b2615b2355]
<br>void dispnextline(flag)
<br> char flag[2];/* R-右光標引起 D-下光標引起 */
<br>{
<br> struct menu *tmppos;
<br> int tmpcurpos;
<br>
<br> tmpcurpos = curpos;
<br> tmppos = scrpos;
<br> if ( flag[0] == 'D') {
<br> while ( tmpcurpos % m_conf.m_col != m_conf.m_col-1) {
<br> tmppos = tmppos->next; tmpcurpos++;
<br> }
<br> tmppos = tmppos->next;
<br> }
<br>
<br> for (tmpcurpos = 0; tmpcurpos < m_conf.m_col; tmpcurpos++) {
<br> wmove(curw, m_conf.m_lengh-1, (tmpcurpos%m_conf.m_col)
<br> *m_conf.m_wight/m_conf.m_col+m_conf.m_col);
<br> wprintw(curw, "%s", tmppos->item);
<br> last=tmppos;/* last 為本頁最后一個結點指針 */
<br> begin=tmppos; tmppos = tmppos->next;
<br> if (tmppos == NULL)
<br> break;
<br> }
<br>}
<br>
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>/* 取指定菜單參數函數 */
<br> [code:1:b2615b2355]
<br>void getmenuconf(menu_code)
<br> short menu_code;
<br>{
<br> FILE *fp;
<br> char menu_buff[0x100];
<br>
<br> if ((fp = fopen("menu.conf", "r"))==NULL) {
<br> fprintf(stderr, "can not open menu config file");
<br> return;
<br> }
<br> while( fgets(menu_buff, 0x100, fp)!=NULL ) {
<br> get_m_conf(menu_buff);
<br> if (m_conf.menu_code == menu_code)
<br> break;
<br> }
<br> return ;
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>
<br>
<br>/* 取指定菜單參數處理函數 */
<br> [code:1:b2615b2355]
<br>void get_m_conf(menu_conf)
<br> char *menu_conf;
<br>{
<br> register i, j, k;
<br> char buff[20];
<br>
<br> j = k = 0;
<br> for (i = 0; i < strlen(menu_conf); i++) {
<br> if ( menu_conf[i] == '!' ) {
<br> j++;
<br> if ( j == 1) {
<br> k = i+1;
<br> continue;
<br> }
<br> switch(j) {
<br> case 2:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.menu_code = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 3:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.last_code = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 4:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.bord_flag = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 5:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.m_wight = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 6:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.m_lengh = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 7:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.m_col = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 8:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.m_bx = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 9:
<br> memcpy(buff, &menu_conf[k], i-k);
<br> buff[i-k]=0;
<br> m_conf.m_by = atoi(buff);
<br> k=i+1;
<br> break;
<br> default:
<br> break;
<br> }
<br> }
<br> }
<br>}
<br>[/code:1:b2615b2355]
<br>
<br>
<br>/* 取指定項參數處理函數 */
<br> [code:1:b2615b2355]
<br>void get_m_item(menu_item)
<br> char *menu_item;
<br>{
<br> register i, j, k;
<br> char buff[80];
<br>
<br> j = k = 0;
<br> for (i = 0; i < strlen(menu_item); i++) {
<br> if ( menu_item[i] == '!' ) {
<br> j++;
<br> if ( j == 1) {
<br> k = i+1;
<br> continue;
<br> }
<br> switch(j) {
<br> case 2:
<br> memcpy(buff, &menu_item[k], i-k);
<br> buff[i-k] = 0;
<br> m_item.menu_code = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 3:
<br> memcpy(buff, &menu_item[k], i-k);
<br> buff[i-k] = 0;
<br> m_item.item_order = atoi(buff);
<br> k=i+1;
<br> break;
<br> case 4:
<br> memcpy(buff, &menu_item[k], i-k);
<br> buff[i-k] = 0;
<br> strcpy(m_item.item,buff);
<br> k=i+1;
<br> break;
<br> case 5:
<br> memcpy(buff, &menu_item[k], i-k);
<br> buff[i-k] = 0;
<br> strcpy(m_item.prog,buff);
<br> k=i+1;
<br> break;
<br> case 6:
<br> memcpy(buff, &menu_item[k], i-k);
<br> buff[i-k] = 0;
<br> m_item.submenu_code = atoi(buff);
<br> k=i+1;
<br> break;
<br> default:
<br> break;
<br> }
<br> }
<br> }
<br>}
<br>
<br>[/code:1:b2615b2355]
<br>
<br>數據結構和頭文件等初始化信息
<br>[code:1:b2615b2355]
<br>#include
<br>#define ESC 27
<br>#define ENT 13
<br>#define REFRESH 12
<br>#define MAX_M 10 /* 菜單最大層數 */
<br>
<br>void initial(),nomlastpos(),revcurpos(),disponepage(),dispprevline();
<br>void dispnextline(),domenu(),getmenuconf(),keycont();
<br>void getitem(), get_m_conf(), get_m_item(),clearwin(),execprog();
<br>/* 標識每一菜單項的結構 */
<br>struct menu {
<br> short menu_code; /* 所屬菜單代號 */
<br> short item_order; /* 項順序號 */
<br> char item[20]; /* 菜單項名稱 */
<br> char prog[80]; /* 本項菜單執行程序 */
<br> short submenu_code; /* 下一級菜單編號 */
<br> struct menu *next; /* 指向上一項的指針 */
<br> struct menu *prev; /* 指向下一項的指針 */
<br>} m_item,*head,*this,*new,*last,*scrpos,*lastscrpos,*begin,*lastbegin,*lastscr[MAX_M];
<br>/* 標識每一菜單內容的結構 */
<br>struct menuconf {
<br> short menu_code; /* 菜單代號 */
<br> short last_code; /* 上一級菜單代號 */
<br> short bord_flag; /* 邊框標志 0--無邊框 1--有邊框 **/
<br> short m_wight; /* 菜單顯示寬度 */
<br> short m_lengh; /* 每一行項數 */
<br> short m_col; /* 菜單列數 */
<br> short m_bx; /* 菜單起始橫坐標 */
<br> short m_by; /* 菜單起始縱坐標 */
<br>} m_conf;
<br>WINDOW *menuwin, *boxwin, *curw, *lastw[MAX_M], *workwin;
<br>long curpos, lastcurpos, lastscrcurpos, lastmenucur[MAX_M];
<br>short menu_no = 0, wno = 0;
<br>
<br>[/code:1:b2615b2355]<br> <br> </td></tr> </table></td></tr><tr><td align=center><small>【<a href=http://www.chinaunix.net/forum/posting.php?mode=reply&t=78395>發表回復</a>】【<a href=http://www.chinaunix.net/forum/viewtopic.php?t=78395>查看CU論壇原帖</a>】【<a href="javascript:window.close()">關閉</a>】</small></td></tr></table><!-----------回復-----------><table border="0" width=75% cellspacing="0" cellpadding="0" ><tr><td bgcolor=#EDF0F5> <table border="0" width=90% cellspacing="0" cellpadding="0" align=center style='border-collapse: collapse; WORD-BREAK: break-all'> <tr><td ><hr><small> <a href=http://www.chinaunix.net/forum/profile.php?mode=viewprofile&u=27601 target=_blank>yikaikai</a> 回復于:2003-05-28 08:10:57</small></td></tr><tr><td>版主加為精華啊<br><br></td></tr><tr><td ><hr><small> <a href=http://www.chinaunix.net/forum/profile.php?mode=viewprofile&u=12254 target=_blank>superzhang</a> 回復于:2003-05-28 08:22:31</small></td></tr><tr><td>確實不錯,值得收藏.<br><br></td></tr><tr><td ><hr><small> <a href=http://www.chinaunix.net/forum/profile.php?mode=viewprofile&u=57921 target=_blank>win_bigboy</a> 回復于:2003-05-28 14:42:32</small></td></tr><tr><td>實在謝謝你了,我一直有寫些 窗口函數的念頭只是一直沒有時間.
<br>還有沒有,<br><br></td></tr><tr><td ><hr><small> <a href=http://www.chinaunix.net/forum/profile.php?mode=viewprofile&u=57921 target=_blank>win_bigboy</a> 回復于:2003-05-28 15:22:46</small></td></tr><tr><td>大師, 有沒有畫Line 和畫 box 的函數???<br><br></td></tr><tr><td ><hr><small> <a href=http://www.chinaunix.net/forum/profile.php?mode=viewprofile&u=20281 target=_blank>天祥星辰</a> 回復于:2003-05-28 15:32:29</small></td></tr><tr><td>好! 收藏! 正需要呢!<br><br></td></tr>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -