C++ 使用c+从另一个内部菜单返回主菜单+;

C++ 使用c+从另一个内部菜单返回主菜单+;,c++,codeblocks,C++,Codeblocks,我想做一个销售点(POS)计划。因此,当你打开程序时,会打开一个菜单(主菜单),这是一个滚动菜单(你可以上下移动,用箭头键选择菜单中的一个项目),其中的项目像“开始工作日”、“统计”、“库存”等等 现在,当您按“开始工作日”(使用enter键)时,您将看到另一个菜单,该菜单将要求“接受订单”……返回主菜单。这就是我发现问题的地方。当我按“返回主菜单”时,我无法返回主菜单 我的尝试 #include<iostream> #include<conio.h> #include&

我想做一个销售点(POS)计划。因此,当你打开程序时,会打开一个菜单(主菜单),这是一个滚动菜单(你可以上下移动,用箭头键选择菜单中的一个项目),其中的项目像“开始工作日”、“统计”、“库存”等等

现在,当您按“开始工作日”(使用enter键)时,您将看到另一个菜单,该菜单将要求“接受订单”……返回主菜单。这就是我发现问题的地方。当我按“返回主菜单”时,我无法返回主菜单

我的尝试

#include<iostream>
#include<conio.h>
#include<string>
#include<windows.h>

using namespace std;

int chk=0;

int sbd(void) //the order menu (start business day -> ' press ENTER')
{
        int pointer=0;
        string order[4]={"TAKE ORDER","CHECK MENU","MEMO","RETURN TO MAIN MENU"};



     while(true)
     {
         system("cls");
         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),14);

        cout<<"\t\t     ZAIKA KATHI ROLLS\n";
        cout<<"\t\t\tORDER MENU\n\n";

         for(int i=0;i<=3;i++)
         {
             if( i==pointer)
             {
                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),11);
                 cout<<"-> "<<order[i]<<endl<<endl;
             }
             else
             {
                 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
                 cout<<"   "<<order[i]<<endl<<endl;
             }
         }
            while(true)
             {
                  if(GetAsyncKeyState(VK_UP)!=0)
                  {
                      pointer-=1;
                      if(pointer==-1)
                      {
                           pointer=3;
                      }

                      break;
                  }
                   else if(GetAsyncKeyState(VK_DOWN)!=0)
                   {
                       pointer+=1;
                       if(pointer==4)
                       {
                         pointer=0;
                       }

                    break;
                   }
                   else if(GetAsyncKeyState(VK_RETURN)!=0)
                   {
                       switch(pointer)
                       {
                           case 3 : return 1;
                       }
                   }
             }
             Sleep(150);
         }





}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{


    int pointer=0;
    int flag=1;
    string menu[6]={"START BUSINESS DAY","CONTINUE BUSINESS DAY","END BUSINESS DAY","INVENTORY MANAGEMENT","STATISTICS","SETTINGS"};

Mainmenu :        while(true)
        {
            system("cls");
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),14);
            int i=0;

            cout<<"\t\t     ZAIKA KATHI ROLLS\n";
            cout<<"\t\t\tMAIN MENU\n\n";

            for(i=0;i<=5;i++)
            {

                if(i==pointer)
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),11);
                    cout<<"-> "<<menu[i]<<endl<<endl;
                }
                else
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
                    cout<<"   "<<menu[i]<<endl<<endl;
                }

            }
            while(true)
            {
                if(GetAsyncKeyState(VK_UP)!=0)
                 {
                     pointer-=1;



                     if(pointer==-1)
                     {
                          pointer=5;
                     }
                    break;
                }
                else if(GetAsyncKeyState(VK_DOWN)!=0)
                {
                    pointer+=1;

                   /* if(flag==0 && pointer==1)
                        pointer=3;

                    if(flag==1 && pointer==0)
                        pointer=1;*/

                    if(pointer==6)
                    {
                         pointer=0;
                    }
                    break;
                }
                else if(GetAsyncKeyState(VK_RETURN)!=0)
                {
                    switch(pointer)
                    {
                        case 0 :chk=sbd();

                                if(chk==1)
                                    goto Mainmenu;






                    }
                }

            }

            Sleep(150);
        }

        return 0;

    }
#包括
#包括
#包括
#包括
使用名称空间std;
int-chk=0;
int sbd(void)//订单菜单(开始工作日->按ENTER键)
{
int指针=0;
字符串顺序[4]={“接受订单”、“检查菜单”、“备忘录”、“返回主菜单”};
while(true)
{
系统(“cls”);
SetConsoleTextAttribute(GetStdHandle(标准输出句柄),14);

cout发生的事情是,当你在“返回主菜单”上按enter键时,它实际上是返回主菜单。如果你调试并单步执行它,你会看到这一点。问题是,它一走出子菜单循环就进入主菜单循环,检查是否“回车”按下,通过条件并再次进入子菜单循环

问题是您没有在代码中正确使用GetAsyncKeyState函数:

if (GetAsyncKeyState(VK_RETURN) != 0)
if (GetAsyncKeyState(VK_RETURN) != 0)
它检查值是否为零。但根据文档,此函数返回一个SHORT

如果按下键,最高有效位为1,否则为0

如果自上次调用GetAsyncKeyState后按键,则最低有效位为1。我假设这是您想要的。因此,首先更改代码中的两个点:

if (GetAsyncKeyState(VK_RETURN) != 0)
if (GetAsyncKeyState(VK_RETURN) != 0)
致:

我们只想检查最低有效位,看看自上次调用该函数以来是否按下了该键。如果这样做,它应该会工作

也可以使用Windows宏这样编写:

if (LOBYTE(GetAsyncKeyState(VK_RETURN)) != 0)
我还应该提到的是,你可能应该用同样的方法来做上键和下键

不过我真的很喜欢,干得不错

编辑:GetAsyncKeyState()返回一个短整数。它很可能是两个字节。当函数返回此值时,它会设置某些位或标志来告诉您信息。正如我所说,最高有效位(最高)告诉您该键是否按下,最低有效位告诉您自上次调用该函数以来是否按下了该键

因此,以二进制形式返回的数字将如下所示(MSB)是最重要的,而(LSB)是最不重要的:

10000000 00000001
^ MSB           ^ LSB
如果这是一个无符号整数,则其值为32769。您不关心该键当前是否已按下,而更关心的是自上次调用该函数以来该键是否已按下。您只关心右侧的位。按位运算符&AND将比较两个位模式,以及当且仅当两个位都按下时如果为1,则会将结果位设置为1。这与掩码一起使用,因此可以说,您可以提取某些值

10000000 00000001 // Original value
00000000 00000001 // The mask
00000000 00000001 // Result
结果是1。然后可以检查值是否为1,如果是,则自上次调用后按键。这是一种非常低级的操作方式,但Windows就是这样工作的,Windows通过提供宏LOBYTE()提供了帮助另一种方法是函数可以为每件事返回带有bool值的class/struct

第二次编辑(进一步解释):

只有在上次调用GetAsyncKeyState后按下该键时,最低有效位才会为1。因此,如果按下enter键并保持按下状态3秒,则仅在第一次调用GetAsyncKeyState时才会设置LSB。但是,MSB将继续返回并设置MSB,因为这表明该键是否正确下面的快速程序应该很好地说明这一点

在我们的例子中,short有2(字节)16位,因此我们将使用right bitshift操作符>>来获得它。我将把返回类型从short转换为USHORT。这是因为对于有符号整数,没有定义位移位,因为右移位可以传播最左边的位。例如:

// Right shifting 7 bits
UNSIGNED INT
1000 0000 >> 7 = 0000 0001

SIGNED INT
1000 0000 >> 7 = 1111 1111 // We may get this instead which is not what we want
启动一个新项目并粘贴该项目,然后运行,尝试按enter键:

#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
    while (true)
    {
        int count = 0;
        USHORT funcResult = 0;

        while ((funcResult = GetAsyncKeyState(VK_RETURN)) != 0) 
            // If MSB or LSB is set then condition is true
        {
            count++;
            cout << "Return pressed " << count << " times in one loop\n";
            cout << "MSB = " << (funcResult >> 15) << '\n';
            cout << "LSB = " << (funcResult & 1) << '\n';
        }
            // You will see that the MSB is always 1, because it tells us
            // if the key is down.

            // However the LSB is 1 only on the first run of the while loop
    }
}
#包括
#包括
使用名称空间std;
int main()
{
while(true)
{
整数计数=0;
USHORT-funcResult=0;
而((funcResult=GetAsyncKeyState(VK_RETURN))!=0)
//如果设置了MSB或LSB,则条件为true
{
计数++;

cout什么是SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),14);?好吧,它只是给它下面的所有文本上色(14是亮黄色的颜色代码)@斑马鱼你可以自己运行代码并查看它。你可以详细说明一下最低有效位的情况吗?我不太清楚。@Rohan我在答案中添加了一点额外的内容。这是一个很酷的菜单系统,特别是完全在命令提示符下编写的。看,我的代码的问题是当我在子菜单中按Enter键时-菜单程序控制到达主菜单,主菜单再次考虑回车键并到达子菜单。因此,基本上,问题是我按下回车键所花费的最小时间对于程序来说是很长的时间,因此它认为这是“自上次调用以来一直按按键”的情况(这完全是我从你的详细而有帮助的答案中所理解的,如果我错了请纠正我)(抱歉,跑出了空间:()你建议我用一个符咒来纠正,但我仍然不明白它是如何工作的。我想我们必须考虑到自从上次CAL以来没有按下按键的情况。