在控制台中滚动菜单

时间:2015-05-26 13:58:09

标签: c++

控制台中的菜单按箭头向上导航。问题:当我选择“输入数字”并且结果消失时,我无法选择另一个菜单项。如何解决?

这是我的C ++代码:

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

using namespace std;

int main()
{
    string Menu[2] = {"Enter number", "Exit"};
    int pointer = 0;

    while(true)
    {
        system("cls");

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
        cout << "Main Menu\n\n";

        for (int i = 0; i < 2; ++i)
        {
            if (i == pointer)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
                cout << Menu[i] << endl;
            }
            else
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
                cout << Menu[i] << endl;
            }
        }

        while(true)
        {
            if (GetAsyncKeyState(VK_UP) != 0)
            {
                pointer -= 1;
                if (pointer == -1)
                {
                    pointer = 1;
                }
                break;
            }
            else if (GetAsyncKeyState(VK_DOWN) != 0)
            {
                pointer += 1;
                if (pointer == 2)
                {
                    pointer = 0;
                }
                break;
            }
            else if (GetAsyncKeyState(VK_RETURN) != 0)
            {
                switch (pointer)
                {
                    case 0:
                    {
                        int number;
                        cout << "\nEnter number --> ";
                        cin >> number;
                        cout << "\nThe number is ";
                        cout << number;
                        Sleep(1000);
                    } break;
                    case 1:
                    {
                        return 0;
                    } break;
                }
                break;
            }
        }

        Sleep(150);
    }

    return 0;
}

也许,最好使用Qt :: Key而不是GetAsyncKeyState?

3 个答案:

答案 0 :(得分:0)

问题是GetAsyncKeyState,

MSDN告诉我们:

  

如果函数成功,则返回值指定是否为键   自上次调用GetAsyncKeyState以来是否被按下,以及是否   密钥当前上升或下降。如果设置了最高位,则   key为down,如果设置了最低有效位,则键为   在上一次调用GetAsyncKeyState之后按下。

因此,在您的情况下,您按Enter键以获取您的号码,因此自上次调用以来已按下回车键,因此(GetAsyncKeyState(VK_RETURN)!= 0)始终为true。 您应该更精确地查看GetAsyncKeyState的返回以查看是否真的按下了键,或者如果在之前的调用中已按下该键则不执行任何操作。小心最后一个选项,其他应用程序或线程也可以调用GetAsyncKeyState。

答案 1 :(得分:0)

当您选择&#34;输入数字&#34;时,您的结果消失的原因是因为每次按下&#34;向上箭头&#34;时,都会使用新字符串重新初始化输出缓冲区。您可以通过将其转换为FSM逻辑来控制状态,并且您的下一个状态取决于当前和之前的状态。目前,您的逻辑只关心当前状态。

答案 2 :(得分:0)

为确保测试某个时刻是否按下某个键,请使用:

short result;
result = GetAsyncKeyState(VK_RETURN);
if (result & 0x8000) { ... }

if (GetAsyncKeyState(VK_RETURN) & 0x8000) { ... }

我在家尝试了这个,但似乎Javia1492是对的,你也有一个我不知道的缓冲问题。尽量不要使用&#34;系统(&#34; cls&#34;)&#34;,它的旧C.尝试编写自己的清除功能,如下面的MSDN上所示:

void cls( HANDLE hConsole )
{
   COORD coordScreen = { 0, 0 };    // home for the cursor 
   DWORD cCharsWritten;
   CONSOLE_SCREEN_BUFFER_INFO csbi; 
   DWORD dwConSize;

   // Get the number of character cells in the current buffer. 

   if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
   {
      return;
   }

   dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

   // Fill the entire screen with blanks.

   if( !FillConsoleOutputCharacter( hConsole,        // Handle to console screen buffer 
                                (TCHAR) ' ',     // Character to write to the buffer
                                dwConSize,       // Number of cells to write 
                                coordScreen,     // Coordinates of first cell 
                                &cCharsWritten ))// Receive number of characters written
   {
      return;
   }

   // Get the current text attribute.

   if( !GetConsoleScreenBufferInfo( hConsole, &csbi ))
   {
      return;
   }

   // Set the buffer's attributes accordingly.

   if( !FillConsoleOutputAttribute( hConsole,         // Handle to console screen buffer 
                                csbi.wAttributes, // Character attributes to use
                                dwConSize,        // Number of cells to set attribute 
                                coordScreen,      // Coordinates of first cell 
                                &cCharsWritten )) // Receive number of characters written
   {
      return;
   }

   // Put the cursor at its home coordinates.

    SetConsoleCursorPosition( hConsole, coordScreen );
}