[PL] FAQ: konsola w Windowsie, kolory, polskie znaki (last update: 2012-12-13, created: 2012-12-09) back to the list ↑
[FAQ - pytania (które dostaje via e-mail/IRC/jabber/etc, oraz na które natrafiam na forach) + moje odpowiedzi]

Topic z forum 4programmers.net, pytanie o dowolne kolory w konsoli Windowsa oraz o polskie znaki. Moja odpowiedź poniżej:

Hey,

[...]

Zgadza się! A konkretniej, jest 16 kolorów z palety którą można samemu zdefiniować (tj. można samemu zdefiniować na Vista/2008/7/etc; nie testowałem na XP, ale wg. MSDN funkcje do redefiniowania palety są dopiero od ww. wersji).

Najpierw obrazek:

16 odcieni fioletu

Przykładowy kod:


// Windows conhost palette change test.
// gynvael.coldwind//vx
// Consider this code public domain
// (except the definitions; they are from MSDN; links below).
// Btw, this required Vista/2008 or newer version of windows.
#include <windows.h>
#include <stdio.h>
 
// Uncomment this if CONSOLE_SCREEN_BUFFER_INFOEX is undefined.
// - This seems to be the case in MinGW Platform API.
// - This is NOT the case for the newest Microsoft Windows Platform SDK.
 
// Source for these definitions: MSDN
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686039(v=vs.85).aspx
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683172(v=vs.85).aspx
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682091(v=vs.85).aspx
/*
typedef struct _CONSOLE_SCREEN_BUFFER_INFOEX {
  ULONG      cbSize;
  COORD      dwSize;
  COORD      dwCursorPosition;
  WORD       wAttributes;
  SMALL_RECT srWindow;
  COORD      dwMaximumWindowSize;
  WORD       wPopupAttributes;
  BOOL       bFullscreenSupported;
  COLORREF   ColorTable[16];
} CONSOLE_SCREEN_BUFFER_INFOEX, *PCONSOLE_SCREEN_BUFFER_INFOEX;
 
extern "C" BOOL WINAPI GetConsoleScreenBufferInfoEx(
  HANDLE hConsoleOutput,
  PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx
);
 
extern "C" BOOL WINAPI SetConsoleScreenBufferInfoEx(
  HANDLE hConsoleOutput,
  PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx
);
*/
 
// Let's test the palette!
int
main(void)
{
  // Set a black into violet gradient.
  CONSOLE_SCREEN_BUFFER_INFOEX bi;
  bi.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
  HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
 
  GetConsoleScreenBufferInfoEx(hcon, &bi);
 
  // Format: 0x00bbggrr
  bi.ColorTable[ 0] = 0x000000; // black
  bi.ColorTable[ 1] = 0x110011; // very dark violet
  bi.ColorTable[ 2] = 0x330033; 
  bi.ColorTable[ 3] = 0x550055;
  bi.ColorTable[ 4] = 0x770077;
  bi.ColorTable[ 5] = 0x990099;
  bi.ColorTable[ 6] = 0xbb00bb;
  bi.ColorTable[ 7] = 0xdd00dd;
  bi.ColorTable[ 8] = 0xff11ff; // violet
  bi.ColorTable[ 9] = 0xff33ff;
  bi.ColorTable[10] = 0xff55ff;
  bi.ColorTable[11] = 0xff77ff; // pink
  bi.ColorTable[12] = 0xff99ff;
  bi.ColorTable[13] = 0xffbbff;
  bi.ColorTable[14] = 0xffddff; 
  bi.ColorTable[15] = 0xffffff; // white
 
  SetConsoleScreenBufferInfoEx(hcon, &bi);
 
  // Test.
  for(DWORD i = 0; i < 16; i++) {
    // Change the color and print a test message.
    SetConsoleTextAttribute(hcon, i);
    printf("This is a test for color %u\n", (unsigned int)i);
 
    // Buffering vs SetConsoleTextAttribute might be a bad idea.    
    fflush(stdout);
  }
 
  // Done.
  return 0;
}


Update:
Ad polskie znaki diakrytyzowane (ąłść etc) w konsoli - tutaj trzeba pamiętać o jednej ważnej zasadzie: nieważne którą "polską" stronę kodową wybierzesz, ważne żeby edytor kodu / tekstu miał ustawioną dokładnie taką samą.
Czyli, jeśli masz edytor który zapisuje kod w utf-8, a stronę ustawisz jako windows-1250 (1250), to pojawią się krzaczki.
Prawdę mówiąc warto aby w ogóle nie trzymać stringów z polskimi znakami w kodzie - najlepiej trzymać je w jakimś pliku tekstowym i je sobie wczytać jako binarne dane. Warto również gdzieś na górze takowego pliku zamieścić informacje o użytym kodowaniu (tak aby następna osoba, która go będzie edytować, nie musiała zgadywać).

Anyway, przykładowy kod z kilkoma różnymi stronami kodowymi obsługującymi polskie znaki:

polskie znaki pod konsolą



// Polish characters in Windows.
// gynvael.coldwind//vx
// Consider this code public domain
#include <windows.h>
#include <stdio.h>
 
int
main(void)
{
  // Kazdy test zawiera nastepujace literki (diakrytyzowane):
  // Aa Ss Zz Zz Oo
  //       ^^^^^
  //       pierwsze z kropeczka, drugie z kreseczka :)
 
  // Przydatny link:
  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
 
  // ibm852 -- OEM Latin 2; Central European (DOS)
  // http://en.wikipedia.org/wiki/Code_page_852
  SetConsoleOutputCP(852);
  puts("Test strony kodowej 852 (ibm852):\n"
       "\xA4\xA5 \x97\x98 \xBD\xBE \x8D\xAB \xE0\xA2\n");
  fflush(stdout); // Buforowanie vs zmiana strony kodowej brzmi jak zly pomysl.
 
 
  // windows-1250 -- ANSI Central European; Central European (Windows)
  // http://en.wikipedia.org/wiki/Code_page_1250
  SetConsoleOutputCP(1250);
  puts("Test strony kodowej 1250 (windows-1250):\n"
       "\xA5\xB9 \x8C\x9C \xAF\xBF \x8F\x9F \xD3\xF3\n");
  fflush(stdout); // Buforowanie vs zmiana strony kodowej brzmi jak zly pomysl.
 
 
  // iso-8859-2 -- ISO 8859-2 Central European; Central European (ISO)
  // http://en.wikipedia.org/wiki/ISO/IEC_8859-2
  SetConsoleOutputCP(28592);
  puts("Test strony kodowej 28592 (iso-8859-2):\n"
       "\xA1\xB1 \xA6\xB6 \xAF\xBF \xAC\xBC \xD3\xF3\n");
  fflush(stdout); // Buforowanie vs zmiana strony kodowej brzmi jak zly pomysl.
 
  // Skipping utf-7 since it shouldn't be used anyway.
  // http://en.wikipedia.org/wiki/UTF-7#Security
 
  // utf-8 -- Unicode (UTF-8)
  // http://en.wikipedia.org/wiki/UTF-8
  SetConsoleOutputCP(65001);
  puts("Test strony kodowej 65001 (utf-8):\n"
       "\xC4\x84\xC4\x85 \xC5\x9A\xC5\x9B \xC5\xBB\xC5\xBC "
       "\xC5\xB9\xC5\xBA \xC3\x93\xC3\xB3\n");
  // Moj edytor zapisuje w utf-8 wiec moglem po prostu napisac:
  //  "Ąą Śś Żż Źź Óó\n"
  fflush(stdout); // Buforowanie vs zmiana strony kodowej brzmi jak zly pomysl.
 
  // Done.
  return 0;
}

【 design & art by Xa / Gynvael Coldwind 】 【 logo font (birdman regular) by utopiafonts / Dale Harris 】