【课程设计】通过c/c++,在控制台实现选择菜单(可通过方向键选择)
前言
以前做课设的时候,费了很大功夫,在windows控制台实现方向键选择菜单。希望可以在这里总结一下,也欢迎大家一起交流学习。
正文
SetConsoleTextAttribute函数
- 以下摘自百度百科 传送门
- SetConsoleTextAttribute是Windows系统中一个可以设置控制台窗口字体颜色和背景色的计算机函数,该函数被广泛应用于软件开发中。
使用此函数前,必须包含Windows.h头文件,即#include <Windows.h>。 - 原型
- BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes);
- SetConsoleTextAttribute是Windows系统中一个可以设置控制台窗口字体颜色和背景色的计算机函数,该函数被广泛应用于软件开发中。
- 宏定义以下代码:
#define IN_RED SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_RED | \
BACKGROUND_INTENSITY)
#define IN_DEFAULT SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
FOREGROUND_RED | \
FOREGROUND_GREEN | \
FOREGROUND_BLUE)
- In_Red,意味着将字体的背景变为红色;而In_DEFAULT,意味着将字体的背景变为默认状态(混合红、绿、蓝)
- 定义函数:
void ShowInRed()
{
IN_RED;
printf("Red\n");
return;
}
- 效果展示:
- 我们注意到后面的语句的背景也变红了。怎么解决这个问题呢?我们只需要在printf执行完之后,调用IN_DEFAULT,将字体背景重置为默认色即可。
- 代码:
void ShowInRed()
{
IN_RED;
printf("Red\n");
IN_DEFAULT;
return;
}
- 结果:
Gotoxy
void Gotoxy(int x, int y)
{
COORD pos = {x, y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
return;
}
- 该函数的用处为将光标移动到(x, y)处
CursorOpr ⋆ ⋆ ⋆ \star\star\star ⋆⋆⋆
下面我们重点来讲以下实现原理
- 原理:通过读取方向键来移动光标,然后用带背景色的字体重新覆盖原本的字体,这样就像是高亮选中了;当离开当前行,选择别的行的时候,就先用默认色覆盖当前行,然后移动光标,高亮覆盖光标后的行,实现退选和再选(如何实现可以看代码注释)
- 代码:
#define UPKEY 72
#define DOWNKY 80 //宏定义上下方向键的ascii值
void Menu() //主菜单
{
printf("欢迎来到学生奖学金管理系统\n");
printf("**************************************************\n");
printf("0) 退出程序\n");
printf("1) 录入学生信息\n");
printf("2) 显示全部学生信息\n");
printf("3) 查找学生信息\n");
printf("4) 删除学生信息\n");
printf("5) 追加学生信息\n");
printf("6) 修改学生信息\n");
printf("7) 统计学生信息\n");
printf("8) 奖学金名单\n");
printf("9) 保存文件\n");
printf("10)备份文件\n");
printf("**************************************************\n");
printf("请使用↑、↓和enter来实现选择和执行命令\n");
printf("或者输入每个命令前面的数字来执行命令<0 - 9>\n");
return;
}
void CursorPos1(int x) //光标覆盖菜单
{
switch (x)
{
case 0:
printf("0) 退出程序 ");
break;
case 1:
printf("1) 录入学生信息 ");
break;
case 2:
printf("2) 显示全部学生信息 ");
break;
case 3:
printf("3) 查找学生信息 ");
break;
case 4:
printf("4) 删除学生信息 ");
break;
case 5:
printf("5) 追加学生信息 ");
break;
case 6:
printf("6) 修改学生信息 ");
break;
case 7:
printf("7) 统计学生信息 ");
break;
case 8:
printf("8) 奖学金名单 ");
break;
case 9:
printf("9) 保存文件 ");
break;
case 10:
printf("10)备份文件 ");
}
return;
}
int CursorOpr(int line, int deta, int lower, int upper, void (*p)(int))
{
/*
line:当前光标所在行数
deta:行数与菜单选项的差值。比如在main菜单中选项(0)在第2行(行数从0开始计算),所以deta等于2,即2 - 0
upper, lower:选项的上下界
(*P)(int):函数指针,选择哪个覆盖菜单
*/
char c1, c2;
Gotoxy(0, line);
do
{
c2 = getch();
if (c2 == DOWNKEY)
{
Gotoxy(0, line);
IN_DEFAULT; //选择默认色
(*p)(line - deta); //覆盖,实现退选
if (line == upper) //如果已经到了上界,则返回下界,实现滚动高亮
line = lower;
else
++line; //行数+1
Gotoxy(0, line);
IN_CYAN;
(*p)(line - deta);
}
if (c2 == UPKEY)
{
Gotoxy(0, line);
IN_DEFAULT;
(*p)(line - deta);
if (line == lower)
line = upper;
else
--line;
Gotoxy(0, line);
IN_CYAN;
(*p)(line - deta);
}
} while ((c1 = getch()) != '\r');
IN_RED;
Gotoxy(0, line);
(*p)(line - deta);
IN_DEFAULT;
return line - deta;
}
文章来源:https://www.toymoban.com/news/detail-728377.html
TheConsoleSize
void TheConsoleSize(int width, int height)
{
char chCmd[32];
sprintf(chCmd, "mode con cols=%d lines=%d", width, height);
system(chCmd);
return;
}
- 该函数的用处为调整控制台的大小
The Whole Code
#include <bits/stdc++.h>
#include <conio.h>
#include <windows.h>
using namespace std;
#define IN_RED SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_RED | \
BACKGROUND_INTENSITY)
#define IN_GREEN SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_GREEN | \
BACKGROUND_INTENSITY)
#define IN_BULE SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_BLUE | \
BACKGROUND_INTENSITY)
#define IN_YELLOW SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_RED | \
BACKGROUND_GREEN | \
BACKGROUND_INTENSITY)
#define IN_CYAN SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_GREEN | \
BACKGROUND_BLUE | \
BACKGROUND_INTENSITY)
#define IN_MAGENTA SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_BLUE | \
BACKGROUND_RED | \
BACKGROUND_INTENSITY)
#define IN_WHITE SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
BACKGROUND_RED | \
BACKGROUND_GREEN | \
BACKGROUND_BLUE | \
BACKGROUND_INTENSITY)
#define IN_DEFAULT SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \
FOREGROUND_RED | \
FOREGROUND_GREEN | \
FOREGROUND_BLUE)
#define UPKEY 72
#define DOWNKEY 80
void Menu()
{
printf("欢迎来到学生奖学金管理系统\n");
printf("**************************************************\n");
printf("0) 退出程序\n");
printf("1) 录入学生信息\n");
printf("2) 显示全部学生信息\n");
printf("3) 查找学生信息\n");
printf("4) 删除学生信息\n");
printf("5) 追加学生信息\n");
printf("6) 修改学生信息\n");
printf("7) 统计学生信息\n");
printf("8) 奖学金名单\n");
printf("9) 保存文件\n");
printf("10)备份文件\n");
printf("**************************************************\n");
printf("请使用↑、↓和enter来实现选择和执行命令\n");
printf("或者输入每个命令前面的数字来执行命令<0 - 9>\n");
return;
}
void CursorPos1(int x)
{
switch (x)
{
case 0:
printf("0) 退出程序 ");
break;
case 1:
printf("1) 录入学生信息 ");
break;
case 2:
printf("2) 显示全部学生信息 ");
break;
case 3:
printf("3) 查找学生信息 ");
break;
case 4:
printf("4) 删除学生信息 ");
break;
case 5:
printf("5) 追加学生信息 ");
break;
case 6:
printf("6) 修改学生信息 ");
break;
case 7:
printf("7) 统计学生信息 ");
break;
case 8:
printf("8) 奖学金名单 ");
break;
case 9:
printf("9) 保存文件 ");
break;
case 10:
printf("10)备份文件 ");
}
return;
}
void TheConsoleSize(int width, int height)
{
char chCmd[32];
sprintf(chCmd, "mode con cols=%d lines=%d", width, height);
system(chCmd);
return;
}
void Gotoxy(int x, int y)
{
COORD pos = {x, y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
return;
}
int CursorOpr(int line, int deta, int lower, int upper, void (*p)(int))
{
/*
line:当前光标所在行数
deta:行数与菜单选项的差值。比如在main菜单中选项(0)在第2行(行数从0开始计算),所以deta等于2,即2 - 0
upper, lower:选项的上下界
(*P)(int):函数指针,选择哪个覆盖菜单
*/
char c1, c2;
Gotoxy(0, line);
do
{
c2 = getch();
if (c2 == DOWNKEY)
{
Gotoxy(0, line);
IN_DEFAULT; //选择默认色
(*p)(line - deta); //覆盖,实现退选
if (line == upper) //如果已经到了上界,则返回下界,实现滚动高亮
line = lower;
else
++line; //
Gotoxy(0, line);
IN_CYAN;
(*p)(line - deta);
}
if (c2 == UPKEY)
{
Gotoxy(0, line);
IN_DEFAULT;
(*p)(line - deta);
if (line == lower)
line = upper;
else
--line;
Gotoxy(0, line);
IN_CYAN;
(*p)(line - deta);
}
} while ((c1 = getch()) != '\r');
IN_RED;
Gotoxy(0, line);
(*p)(line - deta);
IN_DEFAULT;
return line - deta;
}
int main()
{
int n, line = 2; // 对应menu()的1)
char c1, c2;
bool b;
while (1)
{
system("cls");
TheConsoleSize(80, 50);
Menu();
if ((c1 = getch()) == -32)
{
n = CursorOpr(line, 2, 2, 12, CursorPos1);
}
else
{
char tmp;
scanf("%c", &tmp);
if (tmp >= '0' && tmp <= '9')
n = tmp - '0';
else
n = tmp;
}
}
system("pause");
return 0;
}
结语
参考资料
- https://blog.csdn.net/LLLLQZ/article/details/110405100
- https://zxfdog.blog.csdn.net/article/details/103764196
每日一句
我有迷魂招不得,雄鸡一声天下白。
少年心事当拏云,谁念幽寒坐呜呃。
——李贺《致酒行》文章来源地址https://www.toymoban.com/news/detail-728377.html
到了这里,关于【课程设计】Windows控制台上的交互界面(通过c/c++,在windows控制台实现选择菜单(可通过方向键选择))的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!