【课程设计】通过c/c++,在windows控制台实现选择菜单(可通过方向键选择)

【课程设计】通过c/c++,在控制台实现选择菜单(可通过方向键选择)前言正文SetConsoleTextAttribute函数GotoxyCursorOpr

\star\star\star

⋆⋆⋆TheConsoleSizeThe Whole Code

结语参考资料每日一句

【课程设计】通过c/c++,在控制台实现选择菜单(可通过方向键选择)

前言

以前做课设的时候,费了很大功夫,在windows控制台实现方向键选择菜单。希望可以在这里总结一下,也欢迎大家一起交流学习。

正文

SetConsoleTextAttribute函数

以下摘自百度百科 传送门

SetConsoleTextAttribute是Windows系统中一个可以设置控制台窗口字体颜色和背景色的计算机函数,该函数被广泛应用于软件开发中。 使用此函数前,必须包含Windows.h头文件,即#include 。原型

BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes); 宏定义以下代码:

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

}

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

#include

#include

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/110405100https://zxfdog.blog.csdn.net/article/details/103764196

每日一句

我有迷魂招不得,雄鸡一声天下白。 少年心事当拏云,谁念幽寒坐呜呃。 ——李贺《致酒行》

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: