C语言实现一个Window控制台带彩色,且可以用方向键选择并确认的菜单式列表(一)

简介: C语言实现一个Window控制台带彩色,且可以用方向键选择并确认的菜单式列表(一)

在Linux的编程里,管理列表的形式,我们可以使用VT100控制码来进行实现。因为VT100控制码在printf函数中就可以设置显示的行和列,这样实现一个列表选择的GUI界面就非常容易。比如Linux内核中的Make menuconfig。


我们可以看到像下面这样的GUI菜单式界面,这样的界面用Linux VT100控制码结合C语言是很容易就可以实现出来的。

640.jpg

那么,在Window上想要在控制台实现类似的功能,是否也可以做到呢?当然是可以的,Window控制台同样提供了实现这样的函数给开发者来进行使用。说到选择,那么选择就有上下左右四个方向,可以用键盘上的上下左右来进行控制选择。


如何读取对应的键值码呢?我们可以使用C语言的getch()函数获取。通过参考百度百科:https://baike.baidu.com/item/getch()/10996394


我们知道getch()的用法如下:


getch():

所在头文件:conio.h

函数用途:从控制台读取一个字符,但不显示在屏幕上

函数原型:int getch(void)

返回值:读取的字符

例如:

char ch;或int ch;

getch();或ch=getch();

用getch();会等待你按下任意键,再继续执行下面的语句;

用ch=getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。

明白了使用方法,现在我们可以用一个demo程序来测试键盘上按键的键值,方便我们后面实现列表程序:

程序:

find_keyboard_code.c

[cpp] view plain copy

#include <stdio.h>  
#include <conio.h>  
int main(void){  
    int num;  
    printf("please input keyboard num\n") ;  
    while(1)  
    {  
        if((num=getch())<127)  
            printf("num:%d\n",num);  
    }  
    return 0;  
}  

现在我们分别来输入键盘上的上下左右四个按键,如图:

640.png

运行结果:

640.png

演示过程:

640.gif

我们分别得出键盘的上下左右的键值为上:72   下:80   左:75  右:77 , 其它按键给读者自己去测试,这里就不再多说了。


我们以学生信息管理系统为例,分别在这个黑乎乎的终端上显示一个菜单,并且带有彩色,且可以按下上,下按键进行选择。菜单显示的内容如下,且要求内容居中显示:

  "*学生信息添加*",
  "*学生信息查找*",
  "*学生信息打印*",
  "*学生信息修改*",
  "*学生信息删除*",
  "*    退出    *",

关于怎么在Window上显示颜色可以参考这个博主的博客,以及一些网文,链接如下:

http://blog.csdn.net/odaynot/article/details/7722240

http://www.xuebuyuan.com/1674430.html


也可以参考我以前写的文章总结:

http://blog.csdn.net/morixinguan/article/details/52804302


我们来实现这个程序,来看看效果是怎么样的:

student_project_for_window.c

[cpp] view plain copy

#include <stdio.h>  
#include <Windows.h>  
#include <conio.h>  
#include <stdlib.h>  
#define   NR(x)   (sizeof(x)/sizeof(x[0]+0))  
#define  TITLE  "学生信息管理系统"  
#define  AUTHOR "作者:杨源鑫"  
#define  DATE   "日期:2017年8月22日"  
//定义枚举Keyboard的键值数据   
enum   
{  
    UP = 72,  
    DOWN = 80 ,  
    LEFT = 75 ,  
    RIGHT = 77 ,  
    ENTER = 13 ,  
    ESC = 27 ,  
};  
//定义要显示的菜单   
char *menu[] =   
{  
    "*学生信息添加*",  
    "*学生信息查找*",  
    "*学生信息打印*",  
    "*学生信息修改*",  
    "*学生信息删除*",  
    "*    退出    *",  
};  
//定义结构体  
CONSOLE_CURSOR_INFO cci;   
//定义默认的坐标位置       
COORD pos = {0,0};  
//显示菜单   
void showmenu(HANDLE hOut ,char **menu , int size , int index) ;  
//获取用户输入   
int  get_userinput(int *index , int size) ;  
int main()  
{  
    int i;  
    int ret ;  
    int index = 0 ;  
    HANDLE hOut;  
    SetConsoleTitleA(TITLE);  
    //获取当前的句柄---设置为标准输出句柄   
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);  
    //获取光标信息  
    GetConsoleCursorInfo(hOut, &cci);   
    //设置光标大小     
    cci.dwSize = 1;   
    //设置光标不可见 FALSE     
    cci.bVisible =  0;   
    //设置(应用)光标信息  
    SetConsoleCursorInfo(hOut, &cci);     
    while(1)  
    {  
        showmenu(hOut , menu , NR(menu) , index);  
        ret = get_userinput(&index , NR(menu));  
        if(ret == ESC)  
            break ;  
        if(ret == ENTER)  
        {  
            switch(index)  
            {  
                case 0:           break ;   //学生信息添加  
                case 1:           break ;   //学生信息查找  
                case 2:           break ;   //学生信息打印  
                case 3:           break ;   //学生信息修改  
                case 4:           break ;   //学生信息删除  
                case 5:           return 0 ;//退出  
            }  
        }  
    }  
    return 0;  
}  
void showmenu(HANDLE hOut ,char **menu , int size , int index)  
{  
    int i ;   
    system("cls");    
    //设置显示的文本的颜色   
    SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8);   
    //初始化控制台显示的X,Y轴的坐标   
    pos.X = 30;  
    pos.Y = 0 ;  
    //设置显示到控制台终端的具体位置   
    SetConsoleCursorPosition(hOut,pos);      
    //调用printf在控制台对应的位置上输出   
    printf("%s",TITLE);  
    pos.X = 32;  
    pos.Y = 1 ;  
    SetConsoleCursorPosition(hOut,pos);      
    printf("%s",AUTHOR);  
    pos.X = 30;  
    pos.Y = 2 ;  
    SetConsoleCursorPosition(hOut,pos);      
    printf("%s",DATE);  
    for(i = 0 ; i < size ; i++)  
    {  
        //如果i==index表示在当前选项的位置,默认初始化显示是第一项,显示为红色,  
        //当按下上下按键选择的时候,光标会移动,也就看到了列表选择的现象   
        if(i == index)  
        {  
            //红色   
            SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8);   
            pos.X = 30;  
            pos.Y = 5+i;  
            //设置光标坐标  
            SetConsoleCursorPosition(hOut,pos);      
            printf("%s",menu[i]);  
        }  
        //否则显示为白色   
        else  
        {  
            //白色   
            SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);   
            pos.X = 30;  
            pos.Y = 5+i;  
            //设置光标坐标  
            SetConsoleCursorPosition(hOut,pos);    //设置光标坐标  
            printf("%s",menu[i]);  
        }  
    }  
    //刷新标准输出缓冲区   
    fflush(stdout);  
}  
//获取用户输入的接口   
int  get_userinput(int *index , int size)  
{  
    int ch ;  
    ch = getch();  
    switch(ch)  
    {  
        //上   
        //如果选择上,那么光标向上移动   
        case UP : if(*index > 0)  *index -= 1 ;  break;   
        //下   
        //如果选择下,那么光标向下移动   
        case DOWN :if(*index < size -1)  *index += 1 ;  break;  
        //左   
        case LEFT:   
        case 97:return 0 ;  
        //右   
        case RIGHT:return 0 ;  
        //回车   
        case ENTER: return ENTER ;  
        //ESC  
        case ESC: return ESC ;  
    }  
    return 0 ;  
}  

运行结果:

640.jpg

演示结果:

640.gif

当然,程序只是实现了一个简单的列表控制,后面我们再来将这个程序进一步的完善,使它的功能更加的丰富。这样,学生信息管理系统也是可以做得比较有趣的,就没有那么单调了吧,哈哈!


如有兴趣,请持续关注本博客,本博客将为你带来源源不断的干货!

http://blog.csdn.net/morixinguan

目录
相关文章
|
5月前
|
缓存 监控 NoSQL
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
|
7月前
|
编译器 C语言 C++
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(上)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
63 1
|
存储 安全 C语言
|
7月前
|
Java 编译器 C语言
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(下)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
44 0
|
7月前
|
C语言 C++
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(中)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
60 0
|
7月前
|
编译器 C语言
【C语言】—— 可变参数列表
【C语言】—— 可变参数列表
【C语言】—— 可变参数列表
|
7月前
|
C语言
代码(c语言)实现顺序表头尾插入删除(实现菜单)
代码(c语言)实现顺序表头尾插入删除(实现菜单)
69 0
|
7月前
|
C语言
C语言中形参列表为指针的三种不同swap函数的通俗理解
C语言中形参列表为指针的三种不同swap函数的通俗理解
59 0
|
7月前
|
C语言
详解C语言可变参数列表(stdarg头文件及其定义的宏)
详解C语言可变参数列表(stdarg头文件及其定义的宏)
108 0
|
传感器 C语言
C语言表驱动法在定时任务列表中的应用
C语言表驱动法在定时任务列表中的应用
94 0