Tuesday, June 13, 2006
C언어] COLOR 명령 확장: 명령프롬프트 글자색 변경 유틸리티 setclr.exe 만들기
윈도우2000/XP 이상에는 COLOR 라는 명령이 있더군요. "명령 프롬프트"에 출력되는 글자색을 바꾸는 명령입니다:
그런데 COLOR 명령을 주면, 이미 화면에 출력되어 있던 글자들의 색이, 일제히 같은 색으로 변경되어 버리는 문제가 있었습니다.
제가 원하던 것은 특정 문자열에만 색을 주는 것이었는데, COLOR 명령은, 명령 프롬프트 화면 자체의 색을 전부 바꾸어 버리는 것이었습니다.
그래서 특정 문자열의 색만 바꾸는 유틸리티를 하나 만들었습니다. 원래는 Perl(펄)로 만들었는데 속도가 좀 느려서, C로 만들었더니 아주 빠르더군요.
다음의 코드를 setclr.cpp 라는 이름으로 저장한 후 비주얼C 컴파일러로 컴파일하면 setclr.exe 라는 실행파일이 만들어집니다.
옵션 없이 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() 함수 구현
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 [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);
}
#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++)
<< Home