点击这里给我发消息 点击这里给我发消息

C编写类Windows菜单

添加时间:2013-12-7
    相关阅读: 设计 程序 Windows
副标题#e#

    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\",表示主菜单。
    当用户对菜单显示样式不满意时,可通过调整此文件设计个性化的界面。

    二 编程实现
    本程序文件为menu.c,部分代码如下:

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

#p#副标题#e#

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

#p#副标题#e#

    /* 反显当前项函数 */
    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/td>
    for(col=0; 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];

#p#副标题#e#

    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;
    }
    }
    }
    }
    /* 取指定项参数处理函数 */
    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;
    }
    }
    }
    }
    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);
    }
    三 编译说明
    该程序可用如下命令编译(在SCO OpenServer 5.05下编译通过):
    cc -o menu menu.c -lcurses

 

相关C编写类Windows菜单

咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册