ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C/C++ 콘솔창에서 커서를 변경해보자 (GetConsoleScreenBufferInfo, SetConsoleCursorPosition)
    프로그래밍/C/C++ 2023. 1. 19. 09:40

     

    콘솔창에서 메뉴 입력을 받는 영역을 만들고 커서를 제어하여 특정 위치에서 입력을 받게 하고자했다.

     

    위에 이미지와 같이 이미 명령어를 소개하고, 입력값을 소개 테이블 안에서 작성을 하고 싶었다.

     

    일반적으로 콘솔 커서 관련 키워드로 찾아보다가 다음과 같은 코드를 찾을 수 있었다.

     

        COORD Cur;
        CONSOLE_SCREEN_BUFFER_INFO a;
    
    	// 현재 커서 정보를 가져온다
    	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &a);
    	Cur.X = a.dwCursorPosition.X;
    	Cur.Y = a.dwCursorPosition.Y;
        
    	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);

     

    1. 커서 정보를 미리 가져오고, 가져온 커서 정보를 저장해준다.

    2. 화면을 다 채운 후, 미리저장해둔 커서 위치로 커서를 이동시킨다.

     

    그러면 실제로 위에와 같이 출력할 수 있다.

     

    GetConsoleScreenBufferInfo 함수란 무엇인가?

    지정된 콘솔 화면 버퍼에 대한 정보를 검색해주는 함수이다.

    여기서 버퍼란, 단순히 콘솔안에 무슨 내용이 있냐? 라는 정보를 이상으로,

    콘솔상의 커서정보, 콘솔 자체의 크기 등 다양한 정보들을 포괄한다. 해당 버퍼에 대한 내용은 CONSOLE_SCREEN_BUFFER_INFO(consoleapi2.h) 구조체를 참고하면 된다.

    첫번째 매개변수로, 현재콘솔의 핸들 정보를 전달하고,

    두번째 매개변수로 스크린버퍼를 Grab해서 저장할 스크린버퍼 구조체의 주소를 전달하면된다.

     

    SetConsoleCursorPosition 함수란 무엇인가?

    특정 콘솔의 핸들의 커서 위치를 변경하는 함수이다.

    단순하게 콘솔의 핸들을 받고, 이동하고자 하는 좌표를 COORD 구조체에 담아서 전달하면된다.

    일반적으로 콘솔의 특정 위치정보는 스크린버퍼 구조체에 담겨 있으므로,

    스크린버퍼 구조체에서 데이터를 가져와서 COORD 구조체에 넣어주면 된다.

     

    이때 좌표의 기준은 좌표평면의 0좌표가 좌상단을 의미한다.

    void PrintCommand()
    {
    	COORD Cur;
    	CONSOLE_SCREEN_BUFFER_INFO a;
    	int menu_num = 0;
    
    
    	printf("| ---------------------------------------------------------- | \n");
    	printf("| ---------------------- Command Box ----------------------- | \n");
    	printf("| ---------------------------------------------------------- | \n");
    	printf("| [1] 파일로 부터 읽기(base.ini)                             | \n");
    	printf("| [2] 커맨드로 읽기                                          | \n");
    	printf("| ---------------------------------------------------------- | \n");
    	printf("| COMMAND >> ");
    
    	// 현재 커서 정보를 가져온다
    	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &a);
    	Cur.X = a.dwCursorPosition.X;
    	Cur.Y = a.dwCursorPosition.Y;
    	printf("\n"); // newline
    	printf("| ---------------------------------------------------------- | \n");
    	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);
    
    	scanf_s("%d", &menu_num);
    	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur);
    }

    실제 맨 위에 나오는 그림과 같이 출력을 하고, 입력을 받기위해 내가 구현한 함수이다.

     

    처음에는 입력받는 부분이 비어있고 하단에 구분선도 포함이되며,

    입력을 받아 숫자를 입력하면 COMMAND >> ____ 부분에 값이 채워지기를 원했기 때문에 위와 같이

    COMMAND >> 를 print 하고 커서 정보를 저장했다.

    댓글

Designed by Tistory.