mwultong Blog ... 프로그래밍 / 계산기

컴퓨터 엑셀 워드 포토샵 구글어스 WINDOWS JAVASCRIPT JAVA C++

 
Tuesday, June 13, 2006

C언어] COLOR 명령 확장: 명령프롬프트 글자색 변경 유틸리티 setclr.exe 만들기


윈도우2000/XP 이상에는 COLOR 라는 명령이 있더군요. "명령 프롬프트"에 출력되는 글자색을 바꾸는 명령입니다:

D:\Z>color /?
콘솔의 기본 문자색과 배경색을 설정합니다.

COLOR [attr]

   attr        콘솔로 출력되는 색 속성을 지정합니다.

색 속성은 두 자리의 16진수로 지정됩니다. 즉, 첫째 자리는 배경색에 해당되고
둘째 자리는 문자색에 해당됩니다.  각 자리 수는 다음 값이 될 수 있습니다.

   0 = 검정색       8 = 회색
   1 = 파랑색       9 = 연한 파랑색
   2 = 초록색       A = 연한 초록색
   3 = 옥색         B = 연한 옥색
   4 = 빨강색       C = 연한 빨강색
   5 = 자주색       D = 연한 자주색
   6 = 노랑색       E = 연한 노랑색
   7 = 흰색         F = 밝은 흰색

인수가 주어지지 않으면 이 명령은 CMD.EXE가 시작할 때 사용한
색으로 복원됩니다. 값은 현재 콘솔 창에서 가져 오거나, /T 명령 중
스위치나 DefaultColor 레지스트리 값으로부터 가져 옵니다.

COLOR 명령은 문자색과 배경색을 같게 지정하여 실행하려고 할 경우
ERRORLEVEL을 1로 설정합니다.

예를 들면 "COLOR fc"는 밝은 흰색 위에 연한 빨강색의 문자색을 나타냅니다.

D:\Z>


그런데 COLOR 명령을 주면, 이미 화면에 출력되어 있던 글자들의 색이, 일제히 같은 색으로 변경되어 버리는 문제가 있었습니다.

제가 원하던 것은 특정 문자열에만 색을 주는 것이었는데, COLOR 명령은, 명령 프롬프트 화면 자체의 색을 전부 바꾸어 버리는 것이었습니다.


그래서 특정 문자열의 색만 바꾸는 유틸리티를 하나 만들었습니다. 원래는 Perl(펄)로 만들었는데 속도가 좀 느려서, C로 만들었더니 아주 빠르더군요.




다음의 코드를 setclr.cpp 라는 이름으로 저장한 후 비주얼C 컴파일러로 컴파일하면 setclr.exe 라는 실행파일이 만들어집니다.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>

#define THIS_PROGRAM_VERSION "1.0"
char this_program_name[] = "SETCLR";

void setrgb(char *s);
int help(void);



int main(int argc, char *argv[]) {

   if (argc == 1) help();
   setrgb(argv[1]);

   return 0;
}




void setrgb(char *s) {
   WORD attr, previous_background_color;
   char fc, bc;
   HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE); // GetConsoleScreenBufferInfo에 필요
   CONSOLE_SCREEN_BUFFER_INFO csbi;                    // GetConsoleScreenBufferInfo에 필요

   GetConsoleScreenBufferInfo(hConsole, &csbi);
   // 전경색과 배경색이 혼합된 wAttributes에서 배경색만 추출
   // 11111000 등에서 앞의 4비트가 배경색이므로 4비트를 우측으로 이동시켰다가 원위치시키면
   // 뒤의 네자리 즉 전경색은 0000로 채워져 배경색만 남음.
   previous_background_color = csbi.wAttributes >> 0x4;
   previous_background_color = previous_background_color << 0x4;



   strupr(s);
   // 만약 두 색이 모두 지정되어 있으면 처음 숫자는 배경색, 다음 숫자는 전경색.
   // 한 색만 지정돼 있으면 전경색
   // 이것은 MS의 color 명령의 옵션 순서임
   // color 명령은, 한 색만 지정하면 전경색. 두 색을 지정하면 앞색을 배경색으로 인식해 버림.
   if (s[1] != 0) { // 만약 두 색이 모두 지정되어 있으면
      bc = s[0]; fc = s[1];
   } else {         // 한 색만 지정하면
      fc = s[0]; bc = 'X';
   }




   /* Foreground Color */
   switch (fc) {
      case '0': // Black
         attr = 0;
         break;
      case '1': // Blue
         attr = FOREGROUND_BLUE;
         break;
      case '2': // Green
         attr = FOREGROUND_GREEN;
         break;
      case '3': // Aqua (Cyan)
         attr = FOREGROUND_GREEN | FOREGROUND_BLUE;
         break;
      case '4': // Red
         attr = FOREGROUND_RED;
         break;
      case '5': // Purple (Magenta)
         attr = FOREGROUND_RED | FOREGROUND_BLUE;
         break;
      case '6': // Yellow
         attr = FOREGROUND_RED | FOREGROUND_GREEN;
         break;
      case '7': // White (Gray: System Default)
         attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
         break;
      case '8': // Gray (Light Black)
         attr = FOREGROUND_INTENSITY;
         break;
      case '9': // Light Blue
         attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
         break;
      case 'A': // Light Green
         attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
         break;
      case 'B': // Light Aqua (Cyan)
         attr = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
         break;
      case 'C': // Light Red
         attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
         break;
      case 'D': // Light Purple (Magenta)
         attr = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
         break;
      case 'E': // Light Yellow
         attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
         break;
      case 'F': // Bright White
         attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
         break;
      default : help();
         break;
   }




   /* Background Color */
   switch (bc) {
      case 'X': // 배경색이 지정돼 있지 않으면 기존의 배경색을 사용.
                // 전경색만 지정하면 배경색이 항상 검정으로 되어 버림.
         attr = attr | previous_background_color;
         break;
      case '0': // Black
         attr = attr | 0;
         break;
      case '1': // Blue
         attr = attr | BACKGROUND_BLUE;
         break;
      case '2': // Green
         attr = attr | BACKGROUND_GREEN;
         break;
      case '3': // Aqua (Cyan)
         attr = attr | BACKGROUND_GREEN | BACKGROUND_BLUE;
         break;
      case '4': // Red
         attr = attr | BACKGROUND_RED;
         break;
      case '5': // Purple (Magenta)
         attr = attr | BACKGROUND_RED | BACKGROUND_BLUE;
         break;
      case '6': // Yellow
         attr = attr | BACKGROUND_RED | BACKGROUND_GREEN;
         break;
      case '7': // White (Gray: System Default)
         attr = attr | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
         break;
      case '8': // Gray (Light Black)
         attr = attr | BACKGROUND_INTENSITY;
         break;
      case '9': // Light Blue
         attr = attr | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
         break;
      case 'A': // Light Green
         attr = attr | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
         break;
      case 'B': // Light Aqua (Cyan)
         attr = attr | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
         break;
      case 'C': // Light Red
         attr = attr | BACKGROUND_RED | BACKGROUND_INTENSITY;
         break;
      case 'D': // Light Purple (Magenta)
         attr = attr | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
         break;
      case 'E': // Light Yellow
         attr = attr | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
         break;
      case 'F': // Bright White
         attr = attr | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
         break;
      default : help();
         break;
   }

   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
}




int help(void) {
   printf("\n"
      "%s " THIS_PROGRAM_VERSION "\n"
      "(c) 2006 mwultong.blogspot.com\n"
      "\n"
      "Set Console Letter Color (Microsoft COLOR command compatible)\n"
      "\n\n"
      "Usage   : %s < Foreground Color >\n"
      "          %s < Background Color + Foreground Color >\n\n"
      "Example : %s f  :: Bright White\n"
      "          %s 1e :: Bright Yellow on Blue\n"
      "          %s 07 :: White on Black (System Default)\n"
      "\n\n"
      "\t0 = Black (Invisible)               8 = Gray (Dark Gray)\n"
      "\t1 = Blue                            9 = Light Blue\n"
      "\t2 = Green                           A = Light Green\n"
      "\t3 = Aqua (Cyan)                     B = Light Aqua (Light Cyan)\n"
      "\t4 = Red                             C = Light Red\n"
      "\t5 = Purple (Magenta)                D = Light Purple (Light Magenta)\n"
      "\t6 = Yellow                          E = Light Yellow\n"
      "\t7 = White (Gray: System Default)    F = Bright White\n"
      "\n"
      , this_program_name,
        this_program_name, this_program_name,
        this_program_name, this_program_name, this_program_name
      );

   exit(EXIT_FAILURE);
}



옵션 없이 setclr.exe 를 실행하면 도움말이 나옵니다.

setclr f
라고 하면, 그 다음부터 출력되는 글자들은 모두 하얗게 표시됩니다.

setclr c
라고 하면, 그 다음부터 출력되는 글자들은 모두 빨갛게 표시됩니다.

setclr 7
이라고 하면 원래의 색 즉 밝은 회색으로 글자들이 출력됩니다.




물론 이 유틸리티는 그냥 쓰는 것보다는, 배치 파일 속에서 쓰는 것이 적합합니다. 다음과 같이 명령행에서도 배치 파일 비슷하게 실행시킬 수 있습니다.

setclr c & echo Red & setclr f & echo White & setclr 7 & echo Default

명령 프롬프트에서 위와 같은 명령을 준다면

Red
White
Default

가 각각 빨강, 흰색, 회색으로 글자가 나올 것입니다.




추가 사항:
Windows.h 라는 헤더파일이 필요합니다. 참고 : [C언어/C++] 비주얼C로 콘솔 글자 색깔 변경, 볼랜드C++의 textcolor() 함수 구현




tag: cpp
C언어 | C/C++ (Visual C++)

0 Comments:

<< Home RSS 2.0 feed

구글 Google 에서 제공하는 무료 블로그 서비스인 블로거 Blogger 의 인터넷 주소는 www.blogger.com 입니다. Blogger 에 블로그를 만들면, blogspot.com 이라는 주소에 블로그가 생성됩니다.
블로그를 직접 방문하지 않고도 최신 게시물을 구독하려면 RSS 2.0 feed 주소를 리더기에 등록하시면 됩니다.
Previous Posts
Monthly Archives
Top