如何使用箭头键、c 和 win32 在控制台中移动

问题描述 投票:0回答:1

我正在使用 C 编程语言编写文本编辑器,我一直致力于如何让用户能够使用箭头键在控制台中移动,这是我的代码,如果您能提供帮助,那就太好了,谢谢。

// EDIT LOOP
void insertMode(char *buffer, const char *filename)
{
    // Init cursor
    int cursor = strlen(buffer);
    COORD cursorPos = {0, 0};
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);

    BOOL isEditing = TRUE;
    while (isEditing)
    {
        // clear screen, display file contents and show cursor
        system("cls");
        displayBuffer(buffer, filename);

        // Show all instruction to the user
        printf("\nesc = SAVE&QUIT\n");

        // Move the cursor to the current cursorPos
        SetConsoleCursorPosition(console, cursorPos);

        // Capture user input
        char ch = _getch();

        // If 'ESC' key to return to normal mode
        if (ch == 27)
        {
            // Save the file contents before exiting insert mode
            if (saveFile(filename, buffer) == 0)
            {
                system("cls");
                printf("\nFile saved successfully.\n");
            }
            else
            {
                printf("\nError saving file.\n");
            }
            break;
        }
        // 'Backspace' key
        else if (ch == '\b')
        {
            if (cursor > 0)
            {
                buffer[cursor - 1] = '\0';  // Remove last character
                cursor--;
            }
        }
        // 'Enter' key
        else if (ch == '\r')
        {
            if (cursor < MAX_BUFFER - 1)
            {
                // Adds newline
                buffer[cursor] = '\n';
                cursor++;
            }
        }
        else
        {
            // Add the input character to the buffer
            if (cursor < MAX_BUFFER - 1)
            {
                buffer[cursor] = ch;
                cursor++;
                buffer[cursor] = '\0';
            }
        }
    }
}

我尝试使用 gpt 来尝试帮助我使用箭头键移动光标,但不幸的是它不起作用。

c winapi cursor arrow-keys
1个回答
0
投票

这个简单的箭头键演示将完全按照您的要求进行:您可以通过箭头键在 MS Windows 控制台窗口中导航。 它是可扩展的:您可以激活

printf()
中的
GetKey()
来发现 END 和 HOME 键等的键值,然后使光标一直向右和一直向左移动等。

还有其他方法来识别 MS Windows 中的箭头和其他扩展键,但是

GetKey()
非常简单,对于需要立即启动和运行的小项目来说,通常是一个完美的解决方案。

在我看来,

move_xy()
是另一项创新,使该代码以干净简单的方式工作。 它调用
GetConsoleScreenBufferInfo()
来发现当前光标位置,然后根据传入的 X 和 Y 参数修改当前坐标,然后调用
SetConsoleCursorPosition()
将光标移动到所需的新/修改的坐标。

社区:令人遗憾的不可移植 Windows 代码,深表歉意。 但请注意,OP 要求在 ms windows 平台/环境中提供解决方案。

#include <stdio.h>
#include <conio.h>
#include <windows.h>

#define LEFT_ARROW        331
#define RIGHT_ARROW       333
#define UP_ARROW          328
#define DOWN_ARROW        336

HANDLE hConOut = NULL;

/*----------------------------------------------------------- 
* GetKey()
* Assigns unique key value accounting for complexities of 
* extending keys like ARROW and F-Keys.  Thanks John Wagner.
*-----------------------------------------------------------*/
int GetKey()
{
    int key = _getch();
    if(key == 0 || key == 224)
        key = 256 + _getch();
    //printf("key: %d\n", key);
    return key;
}

/*---------------------------------------------------------- 
* move_xy()
* Discovers current cursor coords and moves the cursor
* from those coords depending on params x & y 
*----------------------------------------------------------*/
int move_xy(int px, int py)
{
    BOOL bsuccess = FALSE;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if(GetConsoleScreenBufferInfo( hConOut, &csbi))
    {
        csbi.dwCursorPosition.X += px;
        csbi.dwCursorPosition.Y += py;
        bsuccess = SetConsoleCursorPosition( hConOut, csbi.dwCursorPosition );
    }
    return bsuccess;
}


int main() 
{
    int key, done  = 0;

    hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if(hConOut == INVALID_HANDLE_VALUE)
    {
        printf("STDOUT not available");
        return 0;
    }

    printf("(press esc to exit)\n");
    while(!done)
    {
        key = GetKey(); 
        switch(key)
        {
            case 27: 
                printf("\nESC entered -- Exit\n");
                done = 1;
            break;

            case LEFT_ARROW:  
                move_xy(-1, 0);
            break;
            case RIGHT_ARROW:  
                move_xy(1, 0);
            break;
            case UP_ARROW:  
                move_xy(0, -1);
            break;
            case DOWN_ARROW:  
                move_xy(0, 1);
            break;

            default: 
            break;
        }
    }

    GetKey(); /* Pause for results - wait key press */
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.