void gotoxy(int xpos, int ypos)
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOuput, scrn);
}
作用就是移动光标到 (xpos,ypos),控制台的输出都是在光标后的
输出案例
cout << "hello " << endl;
gotoxy(5, 5);
cout << "world!" << endl;
执行第17行代码时我并没有在键盘按下任何键
通过调试可以知道:_kbhit()函数用于检查键盘是否有输入,如果有则返回非0,否则返回0
.
.
通过调试发现,通过_getch()函数输入的内容 不会出现在控制台上
当键盘输入 ’ ↑ ’ 时,ch赋值为-32,
第二轮循环:缓冲区又为ch赋值72
这个-32应该是键盘有输入的一个标志,
而72是’ ↑’ 对应的ASCII码
这里不在一 一举例,’ ↓ '的ASCII码为80
这里用string数组来存菜单内容,用index来表示菜单的下标
string select[] = { "选项1","选项2","退出3" };
int index = 0;
输出菜单的内容
int main()
{
int index = 0;
char ch;
string select[] = { "选项1","选项2","退出3" };
string str = "-> ";
gotoxy(5, 1);
cout << "enter ↑ ↓ to control system" << endl;
for (int i = 0; i < 3; i++) {
gotoxy(9, 3 + i);
cout << select[i];
}
gotoxy(5, 3);
cout << str+" "+select[0];
}
.
while (true) {
if (_kbhit()) {
ch = _getch();//not print at screen
if (ch == 72 || ch == 80 || ch == '\r')
{
if (ch == 27) {//esc
//...
return -1;
}
else if (ch == 72) {//up
//...执行的语句
index--;
}
else if (ch == 80) {//down
//...执行的语句
index++;
}
if (index < 0) {
index = 2;
}
else if (index > 2) {
index = 0;
}
}
}
}
要实现上下移动最重要的是:新内容的显示与旧内容的擦除
擦除旧内容:
.
这里就能体现用index来选择菜单的内容的原因:
.
以按下键盘的 ’ ↓ ’ 键 来举例,用’ -> ‘来表示当前选择
.
我们希望’->'移到下一行,则这里的index是要自增的
.
同时清楚我们的当前行
.
所以这里我们需要的操作就是
.
// 这里的 %*c 表示79个' ',可以起到清除当前行的效果,79是随便设置的
printf("\r%*c\r", 79, ' ');
gotoxy(9, 3 + index);
cout << select[index];
index--;
上移也是同理。
显示新内容:
.
我这里为了与没有被选中的内容作区分,将被选中的内容的输出右移了一部分
.
被选中的就是这个效果:
.
因为无论是上移还是下移,index都已经自 增/减 过了
.
所以我们只需要将光标移动到当前行(其实是按下按键时的 上/下 一行)
.
输出我们选中的标志 ’ -> ’ 以及菜单内容
.
可以设置一个延时,过渡自然一点,但有没有全凭你自己选择,没有也无影响
.
gotoxy(5, 3 + index);
cout << " ";
Sleep(100);
cout << str + select[index];
.
我们的index并不能无限的自增和自减
.
不仅仅是菜单内容有限,如果不加限制的自增和自减会导致数组越界
.
这里添加符合直觉的限制
.
如果是第一个菜单,上移则选中最后一个菜单项,最后一个菜单项下移则选中第一个菜单项
.
我这里的菜单项只有3个,所以数组的最大下标就是:2
if (index < 0) {
index = 2;
}
else if (index > 2) {
index = 0;
}
#include
#include
#include
#include
using namespace std;
void gotoxy(int xpos, int ypos)
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOuput, scrn);
}
int main()
{
int index = 0;
char ch;
string select[] = { "选项1","选项2","退出3" };
string str = "-> ";
gotoxy(5, 1);
cout << "enter ↑ ↓ to control system" << endl;
for (int i = 0; i < 3; i++) {
gotoxy(9, 3 + i);
cout << select[i];
}
gotoxy(5, 3);
cout << str+" "+select[0];
while (true) {
if (_kbhit()) {
ch = _getch();//not print at screen
if (ch == 72 || ch == 80 || ch == '\r')
{
if (ch == 27) {//esc
cout << "exit system" << endl;
Sleep(2000);
return -1;
}
else if (ch == 72) {//up
printf("\r%*c\r", 79, ' ');
gotoxy(9, 3 + index);
cout << select[index];
index--;
}
else if (ch == 80) {//down
printf("\r%*c\r", 79, ' ');
gotoxy(9, 3 + index);
cout << select[index];
index++;
}
if (index < 0) {
index = 2;
}
else if (index > 2) {
index = 0;
}
}
gotoxy(5, 3 + index);
cout << " ";
Sleep(100);
cout << str + select[index];
if (ch == '\r') {
return index;
}
}
}
}