TC字符界面-菜单程序【原创】

TC字符界面-菜单程序【原创】
2008/03/06 22:58
/*本程序代码属本人原创,未经允许不得转载,谢谢合作
作者:HungryAnt
发布时间:2008-3-6
*/

/*快捷键功能没有提供,因为程序有各自的快捷键*/

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<bios.h>

/*bios_key*/
#define LEFT 0x4B00
#define RIGHT 0x4D00
#define UP    0x4800
#define DOWN 0x5000
#define ENTER 0x1c0d
#define ALT   0x1100
#define ESC   0x011B
#define F1    0x3B00

#define M 3
#define MAX 20
#define B0 4
#define B1 5
#define B2 6
/*B0,B1等必须小于M*/

char *mmenu[M];/*主菜单指针数组*/
char *bmenu_0[B0];/*分菜单0指针数组*/
char *bmenu_1[B1];/*分菜单1指针数组*/
char *bmenu_2[B2];/*分菜单2指针数组*/

void MenuItem(char *menu[],int max,char *pm,...){/*菜单项 可变参数*/
    int i=0;
    char **ppm=&pm;/*ppm为指向指针的指针*/
    while(i<max){/*将传进来的字符串地址全部存入指针数组中*/
        menu[i]=*ppm;
        /*ppm=sizeof(pm)/sizeof(ppm);*/
        ppm++;/*ppm和pm所占字节数都是2,这样就得到了pm后一个指向字符串的指针地址*/
        i++;
    }
}

void MainMenuPaint(int choose){/*主菜单绘制*/
    int i=0,x=1,len;
    int bg=LIGHTGRAY,text=BLACK,h=RED;/*灰底,黑字,红(表示ALT+快捷键)*/
    char t[2];

    window(1,1,80,1);/*主菜单栏*/
    textattr((bg<<4)+text);
    clrscr();
    while(i<M){/*显示各项名称*/
        cprintf(" %s ",mmenu[i]);/*主菜单各项左右各一个空格*/
        i++;
    }
    i=0;
    while(i<M){/*标上快捷键键位和当前选择项加黑*/
        if(i==choose){
            len=x+strlen(mmenu[i])+2;
            for(;x<len;x++){
                gettext(x,1,x,1,t);
                t[1]=(0<<4)+15;/*黑底白字*/
                puttext(x,1,x,1,t);
            }
            i++;
        }
        else{
            x++;
            gettext(x,1,x,1,t);
            t[1]=(bg<<4)+RED;
            puttext(x,1,x,1,t);
            x+=strlen(mmenu[i]);
            x++;
            i++;
        }
    }
}

void BMenuPaint(char *menu[],int lx,int mx,int my,int bchoose){/*分菜单绘制*/
    int bg=LIGHTGRAY,text=BLACK;/*颜色设置*/
    int i,j;
    char t[2];


    window(lx,2,lx+mx-1,my+1+1);/*创建窗口*/
    textattr((bg<<4)+text);
    clrscr();

    gotoxy(1,1);/*相对于当前窗口*/
    for(j=0;j<mx;j++)putch(196);

    i=0;
    while(i<my){
        gotoxy(1,i+2);
        printf(" %s ",menu[i]);
        i++;
    }
    i=bchoose;
    for(j=0;j<mx;j++){
        gettext(lx+j,i+3,lx+j,i+3,t);
        t[1]=(BLACK<<4)+WHITE;
        puttext(lx+j,i+3,lx+j,i+3,t);
    }
}



int BMenuChoose(int choose){/*分菜单选择,并绘制*/
    char *menu[MAX];
    char *pt;/*储存被分菜单暂时覆盖部分的内容*/
    int my=0,lx,mx=0,bchoose=0,i,l,key;
    switch(choose){/*@@@@@@@@@@@@@@添加分菜单需要在此处添加相应代码*/
    case 0:/*分窗口0*/
        my=B0;/*此处用来设置分窗口共多少项,B0为预处理*/
        for(i=0;i<B0;i++)menu[i]=bmenu_0[i];/*将bmenu_0指针数组所有指向的地址传给menu指针数组*/

        lx=1;/*mx表示分菜单窗口左侧x坐标*/
        break;
    case 1:/*分窗口1*/
        my=B1;
        for(i=0;i<B1;i++)menu[i]=bmenu_1[i];
        lx=1+strlen(mmenu[0])+2;
        break;
    case 2:/*分窗口2*/
        my=B2;
        for(i=0;i<B2;i++)menu[i]=bmenu_2[i];
        lx=1+strlen(mmenu[0])+2;
        lx+=strlen(mmenu[1])+2;
        break;
    }
    i=0;

    while(i<my){/*使mx为大小为最长字符串的长度*/
        l=strlen(menu[i]);
        if(mx<l)mx=l;
        i++;
    }
    mx+=2;/*是项目左右各一个空格*/

    /*储存被分菜单暂时覆盖部分的内容*/
    pt=(char *)malloc(mx*(my+1)*2);/*my+1用意在于本菜单显示时会多一行横线*/
    gettext(lx,2,lx+mx-1,(my+1)+1,pt);

    BMenuPaint(menu,lx,mx,my,bchoose);

    while(1){
        if(bioskey(1)){
            key=bioskey(0);
            switch(key){
            case DOWN:
                bchoose=(bchoose<my-1)?bchoose+1:0;
                BMenuPaint(menu,lx,mx,my,bchoose);
                break;
            case UP:
                bchoose=(bchoose>0)?bchoose-1:my-1;
                BMenuPaint(menu,lx,mx,my,bchoose);
                break;
            case RIGHT:
            case LEFT:
                free(pt);
                puttext(lx,2,lx+mx-1,(my+1)+1,pt);/*覆盖区域复原*/
                return key;/*返回kay值*/

            case ENTER:
            case ESC:
                free(pt);
                puttext(lx,2,lx+mx-1,(my+1)+1,pt);/*覆盖区域复原*/
                return;
            }

        }
    }

}



void ChooseMainMenu(int choose){/*主菜单选择*/
    int key=0,at=0;
    MainMenuPaint(0);/*菜单项选择自动设为0*/
    key=BMenuChoose(0);
    if(key==RIGHT || key==LEFT)at=1;
    else at=0;
    while(1){
        if(bioskey(1) || at){/*at为自动,此用意是让切换分菜单切换加快*/
            if(at!=1)key=bioskey(0);
            switch(key){
            case RIGHT:
                choose=(choose<M-1)?choose+1:0;
                MainMenuPaint(choose);
                key=BMenuChoose(choose);/*分菜单选择调用*/
                /*返回值赋给key,是用来方便从*/
                if(key==RIGHT || key==LEFT)at=1;
                else at=0;
                break;
            case LEFT:
                choose=(choose>0)?choose-1:M-1;
                MainMenuPaint(choose);
                key=BMenuChoose(choose);/*分菜单选择调用*/
                if(key==RIGHT || key==LEFT)at=1;
                else at=0;
                break;

            case ENTER:
            case ESC:return;
            }

        }
    }
}


int main(){
    int key,i;
    MenuItem(mmenu,M,"HungryAnt","Author","Help");/*主菜单*/
    /*用可变参数就是怎么爽,但字符串数量需要和M值相等,不能太多,仅支持一行显示*/

    MainMenuPaint(-1);/*菜单项选择*/

    MenuItem(bmenu_0,B0,"HungryAnt","I really","love you!!!","Good bye!");/*分菜单*/
    MenuItem(bmenu_1,B1,"HungryAnt","abcdffff","1223312","567","HHHH");
    MenuItem(bmenu_2,B2,"H","I","l","G","G","Good bye!");


    window(1,2,80,25);
    textattr((BLUE<<4)+WHITE);
    clrscr();
    /*for(i=0;i<B1;i++){
        printf(" %s /n",bmenu_1[i]);
    }
    getch(); */

    cprintf("Press F1 to the Main Menu...");

    while(1){
        if(bioskey(1)){
            key=bioskey(0);
            switch(key){
            case F1:
                ChooseMainMenu(0);/*主菜单选择,先设为0*/
                exit(1);
            }
        }
    }


    getch();

转载于:https://www.cnblogs.com/gods/archive/2008/03/26/3887673.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 位运算_java学习之运算符与表达式(四)

(6)位运算符位运算是指对整数按二进制的位进行运算。位运算用于整数或字符类型。有7个&#xff1a;~(非)、&(与)、&#xff5c;(或)、^(异或)、<>(右移)、>>>(无符号右移)。例&#xff1a;以byte类型4为例。byte类型占用1个字节。4的二进制为&#xff1a;00…

【Http】一文备忘Http状态码(406,415,422)

最近在调试接口时&#xff0c;web api 报了一个415状态码。好久没见到这个状态码&#xff0c;一时还真不知道啥情况。所以&#xff0c;人的大脑是有遗忘规律的&#xff0c;为了加深印象&#xff0c;所以我觉得我有必要再复习一下。1.HTTP的状态码 首先复习一下所有的状态码。1x…

mysql innodb 多线程插入_mysql innodb 并发插入问题,包大量死锁错误

开了10个并发写线程&#xff0c;没1000条记录批量提交一次&#xff0c;结果mysql包大量死锁错误&#xff01;"Deadlock found when trying to get lock; try restarting transaction"引擎用的是Innodb 主键字段是auto_increament.mysql 有这么脆弱吗&#xff1f;crea…

什么是SEO策略呢

从2005年后&#xff0c;我基本都只是给大型网站做SEO&#xff0c;因为给大型网站做SEO&#xff0c;效果非常的明显&#xff0c;价格自然也可以收的非常高。总结这两年来我做过的几十家大型网站的SEO经验&#xff0c;我发现&#xff0c;SEO策略是最为重要的。什么是SEO策略呢&am…

infor wms 项目启动_广汽本田增城工厂No.2L WMS项目正式启动

Warehouse导读&#xff1a;近日&#xff0c;在生管科No.2L办公室&#xff0c;广汽本田增城工厂No.2L WMS项目启动大会如期召开。生产管理科&#xff0c;IT科&#xff0c;FNL以及汉得信息有限公司的WMS项目组成员参加了本次启动大会。Management2018年10月&#xff0c;生管科已经…

mysql动态扩展_动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis

背景&#xff1a;现有业务扩展字段&#xff0c;都存在feature字段&#xff0c;存在语义不清晰以及&#xff0c;难以利用索引查询问题Mysql 5.7后推出利器&#xff0c;JSON虚拟列&#xff0c;即实现了业务语义统一&#xff0c;也支持索引查询加速一、简单描述MySQL 5.7.7 labs版…

asp.net core安全事项(中)

上传文件上传文件是造成风险的很大因素&#xff0c;所以对上传文件进行处理是重要的&#xff0c;首先要处理的是&#xff1a;a、上传文件大小限制&#xff1b;b、上传文件类型(能过扩展或&#xff0c;或文件头)限制&#xff1b;c、上传的名称要替换掉&#xff1b;d、上传的文件…

TCL:花开刹那还是浴火重生

TCL&#xff1a;花开刹那还是浴火重生 [url]http://www.sina.com.cn[/url] 2008年04月07日 15:24 民营经济报本报记者 叶键 TCL3月份公布了2007年财报&#xff0c;公司净利润达3.9亿元&#xff0c;并于3月27日“摘星脱帽”&#xff0c;恢复为“TCL集团”的自由身&#xff0c;…

http referer 验证防御方法_渗透测试 跨站攻击防御与安全检测手法剖析

上一节讲到了渗透测试中xss跨站攻击检测方法和防护,这一节也是关于跨站攻击的另一个手法CSRF&#xff0c;很多客户找到我们想要了解更多的跨站攻击检测方法以及防御此类攻击的办法,想要让网站的安全性更加坚固,对此提醒大家渗透测试网站必须要拿到授权才能测试哦&#xff01;3.…

如何手动连上mysql_如何手动安装MySql

想安装当然要先有一个MySql的安装包 这里使用的是mysql-5.7.12-winx64安装包百度云&#xff1a;http://pan.baidu.com/s/1kVAuXuv       密码&#xff1a;hr391.要将压缩包解压到你的指定位置(最好将要用的工具文件分类放好)例如&#xff1a;D:javaAppmysql-5.7.12-winx6…

WebRTC成为W3C和IETF正式标准

喜欢就关注我们吧&#xff01;2021年1月26日&#xff0c;W3C&#xff08;万维网联盟&#xff09;和 IETF &#xff08;互联网工程任务组&#xff09;同时宣布 WebRTC&#xff08;Web Real-Time Communications&#xff0c;Web 实时通信&#xff09;现发布为正式标准&#xff0c…

weblogic搭建

weblogic的安装过程&#xff1a;首先下载server910_linux32.bin文件&#xff0c;你可以有多种打开方式&#xff0c;可以通过命令行&#xff0c;但我更偏重于双击打开&#xff0c;然后一路next,当然过程中的一些许可要求你的接受,好了 weblogic的第一步安装完成。接着创建weblog…

ironpython3发布时间_.NET 基金会项目介绍-DLR/IronPython2/IronPython3

DLR/IronPython2/IronPython3 是属于 .Net 基金会的一个项目&#xff0c;本文将简要介绍该项目相关的信息。 中文介绍中文介绍内容翻译自英文介绍&#xff0c;主要采用意译、如与原文存在出入&#xff0c;请以原文为准。 DLR/IronPython2/IronPython3 DLR 是基于 .NET Framewor…

mysql非安装_mysql 非安装版的配置

一直以来都是使用wamp中集成的mysql数据库&#xff0c;今天突然想试试下载一个mysql的zip包进行配置。一、下载mysql非安装版下载地址可以到&#xff1a;http://dev.mysql.com/downloads/mysql/ &#xff0c;或者直接点击下载mysql-32bit&#xff1a;http://cdn.mysql.com/Down…

Xamarin.Forms: 无限滚动的ListView(懒加载方式)

说明 在本博客中&#xff0c;学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView。这个无限滚动函数在默认的Xamarin.Forms不存在&#xff0c;因此我们需要为此添加插件。在这里我们需要知道无限滚动时如何工作的。首先&#xff0c;显示固定的数据。一旦用户…

Lucifer的一场暴强围英雄表演

http://w3g.replays.net/doc/cn/2008-4-9/12077828953425064279.html围所欲围

javaweb应用开发与实践pdf_基于阿里云打造「云原生」Web应用——「懒猪行」Web应用开发实践...

作者&#xff1a;阿里云MVP 刘远程背景『懒猪行』专注于境外自由行S2B业务&#xff0c;涉及分销、终端用户服务、供应链等多个服务环节&#xff0c;随着业务规模的不端增加&#xff0c;我们一直在探索Web应用开发的最佳实践&#xff0c;以加快Web应用的迭代效率&#xff0c;为B…

python大型项目中的日志模块_Python中日志模块的使用

前言程序和脚本往往是无人值守运行的&#xff0c;一旦发生问题&#xff0c;就需要我们去追溯当时的情况来定位问题的原因。这便需要我们在程序和脚本中引入日志的功能。相比于print信息&#xff0c;使用logging日志有以下优点可以记录输出日志的时间、文件、函数以及代码行&…

OSI强调:SSPL并不是开源许可证

喜欢就关注我们吧&#xff01;日前&#xff0c;开放源代码促进会 OSI&#xff08;Open Source Initiative&#xff09;强调&#xff0c;SSPL 并不是一个开源许可证。OSI 表示&#xff0c;SSPL&#xff08;Server Side Public License&#xff09; 是一种典型的 “fauxpen”&…

.NET Remoting

轉自:http://www.iiiedu.org.tw/knowledge/knowledge20030430_2.htm.NET Remoting 資策會數位教育研究所講師 董淑惠     概念簡介 微軟以往使用COM/DCOM的技術來處理分散式系統架構&#xff0c;透過Client端的Proxy代理程式來呼叫遠端Server機器上的物件。.NET Framework則…