正文

下拉式菜单程序(C)2007-03-22 11:21:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lingdlz/24184.html

分享到:

/* * 很久没在TC下写过程序了,本以为一个下拉菜单不出三小时就可以OK谁知道从昨天上午 * 开始到今天上午才完成。当然这里学到了些东西,以前没用过函数指针,现在这个下拉 * 菜单的菜单处理函数都用到了函数指针,调用时是直接通过函数指针,这简化了程序的 * 编写但实际上是不能那样的不同的菜单项应该有不同的处理函数,不过作为学习还是可 * 以的;以前没搞过远堆的内存,这次本来想用远堆来保存屏幕状态,但老是出错,最后 * 还是搞了个全局变量。 * 程序从 main()开始首先初始化界面,然后由用户选择菜单以调用不同的函数,最后通 * 过 ESC 键或者选择 EXIT 菜单退出。整个操作只有 ESC,回车键 和 方向键 有效。本来 * 还想设置菜单的快捷键,以及设计一些 3D 效果,考虑到初学者的接收能力和程序的复杂 * 度,最后还是从简了。 * 记得开始学 C 的时候自己就很想编个下拉菜单,那时候无从下手,对下拉菜单感到很神秘 * 嘿嘿,其实没什么,就是下面这样的。写了详细的注释供初学者参考,学了差不多两年了 * 还是改不掉写代码的坏习惯,变量名没有见名知义,神秘数字从天而降 …… *     不知道大家是怎么写代码的,我一写就停不下来,一搞就是好几个小时,肚子饿得咕 * 咕叫,下楼都没劲,整个人就像散了架。埃,难怪说程序员做不了几年,希望自己不在那样 * 希望天下程序员身体健康 . *                           ----- 江南孤峰 ------ *                             2007 -- 3 -- 22 */ /*** ***   下拉式菜单程序, 编译环境 TC   点击下载源码 ***   转载请注明出处:http://lingdlz.programfan.com ***/#include <stdio.h>#include <conio.h> /* 键盘键值 */#define ESC    0x011b#define DOWN   0x5000#define LEFT   0x4b00#define RIGHT  0x4d00#define UP     0x4800#define ENTER 0x1c0d /* 一般常量宏 */#define SHOW_HIGH BLACK   /* 高亮显示子菜单  */#define SHOW_NORMOL WHITE  /* 正常显示子菜单    */#define MAIN_MENU_C CYAN  /* 当前菜单显示背景色 */#define MENU_LENGTH 20   /* 子菜单名的字符长度  */#define MAIN_MENU_LENGTH 10  /* 主菜单名的长度限制  */ /* 菜单以及子菜单结构 */typedef struct menuItem{   /* 子菜单结构  */ char name[MENU_LENGTH];  /* 菜单选项  */ void (*pFun)(char *name); /* 函数指针  */}TypeMenuItem; typedef struct menu{    /* 菜单结构  */ int count;     /* 子菜单数目  */ char name[MENU_LENGTH];  /* 菜单名  */ TypeMenuItem *pItem;  /* 指向子菜单  */}TypeMenu; char video[2048];   /* 用来保存屏幕 */ /* 初始化屏幕界面 */void InitFace(void){ textbackground(SHOW_HIGH); textcolor(SHOW_NORMOL); clrscr(); gotoxy(24,3); printf("POPUP MENU (c)2007 -- 2088 BY DENG"); window(10,4,70,21); textbackground(RED); clrscr(); window(12,5,68,20); textbackground(SHOW_HIGH);  clrscr(); window(12,5,68,7); textbackground(BLUE); clrscr();}/* 以 show[高亮或者正常]方式在屏幕输出字符串 txt */void WriteText(int x,int y,int xx,int yy,char *txt,int show){ window(x,y,xx,yy); textbackground(show); textcolor((show == SHOW_HIGH ? SHOW_NORMOL : SHOW_HIGH)); clrscr(); gotoxy(2,1); cprintf("%s",txt);}/* 退出程序 */void MyExit(void){ gotoxy(1,2); printf("press any key to exit ..."); getch(); exit(0);}/* 菜单处理函数,实际应用应该根据不同需要设置这些函数 */void menu1_fun1(char* txt){ cprintf("I get:[ %s ]",txt);}void menu1_fun2(char* txt){ cprintf("I get:[ %s ]",txt);}void menu1_fun3(char* txt){ cprintf("I get:[ %s ]",txt);}void menu1_fun4(char* txt){ cprintf("I get:[ %s ]",txt); MyExit();}void menu2_fun1(char* txt){ cprintf("I get:[ %s ]",txt);}void menu2_fun2(char* txt){ cprintf("I get:[ %s ]",txt);}void menu2_fun3(char* txt){ cprintf("I get:[ %s ]",txt);}void ShowHelp(char* txt){ cprintf("I get:[ %s ]",txt); gotoxy(1,2); cprintf("Use Destination key to move"); gotoxy(1,3); cprintf("Use Enter key to select "); gotoxy(1,4); cprintf("Use ESC Key to Exit");}void ShowAbout(char* txt){ cprintf("I get:[ %s ]",txt); gotoxy(1,2); cprintf("The program is write by JiangNanGuFeng"); gotoxy(1,3); cprintf("Only for study,you can update and send"); gotoxy(1,4); cprintf("But you can't delete the followed info"); gotoxy(1,5); cprintf("MY QQ: 403324669\nEmail: lingdlz@163.com"); gotoxy(1,6); cprintf("MY Email: lingdlz@163.com"); gotoxy(1,7); cprintf("MY Blog:http://lingdlz.programfan.com"); gotoxy(1,8); cprintf("Welcome to join QQ group : 28011342"); gotoxy(16,9); cprintf("-- 2007 - 3 - 22 --");}/* 绘制菜单条 */void DrawMenu(TypeMenu pMenu[],int count){ int i,xleft = 13,xright = xleft+MAIN_MENU_LENGTH;  WriteText(xleft,6,xright,6,pMenu[0].name,MAIN_MENU_C); for(i = 1; i < count; i ++){  xleft = xright + 2; /* 2 是菜单之间的分隔长度 */  xright = xright + MAIN_MENU_LENGTH + 2;  WriteText(xleft,6,xright,6,pMenu[i].name,SHOW_NORMOL); }}/* 设置相应坐标 flag 为 0 取主菜单坐标,否则取下拉菜单的坐标 */void SetCoordinate(int *x,int *y,int *xx,int *yy,int cMenu,int cItem){ int xleft = 13,xright = xleft + MAIN_MENU_LENGTH;  *x = xleft + cMenu * (MAIN_MENU_LENGTH + 2); if(cItem){  *y = *yy = 6 + cItem; /* 2 是菜单之间的分隔长度 */  *xx = xright + cMenu * (MAIN_MENU_LENGTH + 2) +    MENU_LENGTH - MAIN_MENU_LENGTH; } else{  *xx = xright + cMenu * (MAIN_MENU_LENGTH + 2);  *y = *yy = 6; }}/* 显示子菜单 */void SpreadMenu(TypeMenu pMenu[],int cMenu){ int i,x,y,xx,yy;  SetCoordinate(&x,&y,&xx,&yy,cMenu,1); WriteText(x,y,xx,y,pMenu[cMenu].pItem[0].name,SHOW_HIGH); for(i = 1,y ++; i < pMenu[cMenu].count; y ++,i ++)  WriteText(x,y,xx,y,pMenu[cMenu].pItem[i].name,SHOW_NORMOL);}/* 程序运行的主要函数 */void RunProgram(TypeMenu pMenu[],int count){ int  MenuSpread,temp;   /* 菜单是否下拉 */ int  cMenu,cItem;   /* cMenu 当前菜单 cItem 当前子菜单 */ int  x,xx,y,yy,uKey;   /* uKey 接收用户输入 */  MenuSpread = cMenu = cItem = 0; while(1){  while(!kbhit()) ;  /* 等待按键 */  uKey = bioskey(0);  switch(uKey){      case ENTER:    if(MenuSpread && cItem){      puttext(12,7,68,21,video);      window(14,8,66,19); /* 信息输出区 */      textcolor(WHITE);      textbackground(BLACK);      clrscr();  /* 下面调用处理函数 */      pMenu[cMenu].pItem[cItem-1].pFun(      pMenu[cMenu].pItem[cItem-1].name );      MenuSpread = cItem = 0;    }    else{   /* 菜单下拉 */      gettext(12,7,68,21,video);      SpreadMenu(pMenu,cMenu);      MenuSpread = 1;  /* 标记菜单已经下拉 */      cItem = 1;  /* 第一个子菜单高亮 */    }    break;    case LEFT:    case RIGHT:   SetCoordinate(&x,&y,&xx,&yy,cMenu,0);   WriteText(x,y,xx,yy,pMenu[cMenu].name,SHOW_NORMOL);   if(MenuSpread){     if(uKey == LEFT)    cMenu = (cMenu == 0 ? count-1 : cMenu-1);     else    cMenu = (cMenu == count-1 ? 0 : cMenu+1);     puttext(12,7,68,21,video);     SpreadMenu(pMenu,cMenu);     cItem = 1;         }         else{     if(uKey == LEFT)    cMenu = (cMenu == 0 ? count-1 : cMenu-1);     else    cMenu = (cMenu == count-1 ? 0 : cMenu+1);         }        SetCoordinate(&x,&y,&xx,&yy,cMenu,0);        WriteText(x,y,xx,yy,pMenu[cMenu].name,MAIN_MENU_C);        break;    case UP:    case DOWN:   if(MenuSpread){     SetCoordinate(&x,&y,&xx,&yy,cMenu,cItem);     WriteText(x,y,xx,yy,pMenu[cMenu].pItem[cItem-1].name,SHOW_NORMOL);     temp = cItem;     if(uKey == DOWN)    cItem = (pMenu[cMenu].count == cItem ? 1 : cItem+1);     else    cItem = (cItem == 1 ? pMenu[cMenu].count : cItem-1);     if(temp > cItem)    y = yy = y - temp + cItem;     else    y = yy = y + cItem - temp;     WriteText(x,y,xx,yy,pMenu[cMenu].pItem[cItem-1].name,SHOW_HIGH);         }         else if(uKey == DOWN){ /* 菜单下拉 */      gettext(12,7,68,21,video);     SpreadMenu(pMenu,cMenu);     MenuSpread = 1;  /* 标记菜单已经下拉 */     cItem = 1;  /* 第一个子菜单高亮 */         }          break;    case ESC:    window(14,8,66,19);    clrscr();   MyExit();     default: break;    } }} void  main(void){ TypeMenu pMenu[3] = {  4,"FILE",NULL,  3,"EDIT",NULL,  2,"HELP",NULL }; TypeMenuItem menu1[] = {      "MENU1_FILE_OPEN",menu1_fun1,      "MENU1_FILE_SAVE",menu1_fun2,      "MENU1_FILE_NEW",menu1_fun3,      "EXIT",menu1_fun4 }; TypeMenuItem menu2[] = {      "MENU2_EDIT_CUT",menu2_fun1,      "MENU2_EDIT_COPY",menu2_fun2,      "MENU2_EDIT_FIND",menu2_fun3 }; TypeMenuItem menu3[] = {      "HELP_ITEM",ShowHelp,      "HELP_ABOUT",ShowAbout }; pMenu[0].pItem = menu1; pMenu[1].pItem = menu2; pMenu[2].pItem = menu3; InitFace(); DrawMenu(pMenu,3); RunProgram(pMenu,3);}

阅读(6323) | 评论(8)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册