IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Pokročilá práce s konzolí v C++

V následujícím tutoriálu si ukážeme, jak změnit barvu textu v konzoli. Dále nastavíme konzoli titulek a naučíme za měnit pozici kurzoru nebo ho úplně vypnout.

Změna barvy textu v konzoli

Začneme tím, že si vytvoříme nový projekt (nebo otevřeme starý) a do souboru s kódem vložíme asi tohle:

#include <iostream>  //standartní výstup
#include <windows.h> //tady jsou definované funkce, které budeme používat
using namespace std;

int main(void)
{
    cin.get(); //opatření, aby se program hned neukončil a čekal na stisk kávesy Enter
    return 0;
}

Asi nejjednodušší způsob jak změnit barvu textu je použít funkci system(). Té jako parametr předáme řetězec "color xy", kde za x a y dosadíme šestnáctkové hodnoty 0-F. X mění barvu pozadí a y barvu textu.

číslo barva
0 ponechat původní barvu
1 tmavě modrá
2 tmavě zelená
3 tmavě tyrkysová
4 tmavě červená
5 tmavě růžová (fialová)
6 tmavě žlutá
7 šedá
8 tmavě šedá
9 modrá
A zelená
B tyrkysová
C červená
D růžová (fialová)
E žlutá
F bílá

Například pro tmavě zelený text na modrém pozadí stačí napsat:

system("color 92");

Hlavní nevýhoda této funkce je, že změní barvu veškerého textu. Pokud chceme měnit jen jeho část, musíme na to jít složitěji. Asi nejlepší je použít:

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), /*barva*/)

K tomu si připravíme seznam barev (všimněte si stejného pořadí barev jako u funkce system()):

#define black 0
#define dark_blue 1
#define dark_green 2
#define dark_cyan 3
#define dark_red 4
#define dark_magenta 5
#define dark_yellow 6
#define grey 7
#define dark_grey 8
#define blue 9
#define green 10
#define cyan 11
#define red 12
#define magenta 13
#define yellow 14
#define white 15

nebo

enum Colors{black, dark_blue, dark_green, dark_cyan, dark_red, dark_magenta, dark_yellow, grey, dark_grey,
    blue, green, cyan, red, magenta, yellow, white};

Pak si vytvoříme funkci pro změnu barvy:

void set_text_color(int background_color, int foreground_color)
{
    //barvu získáme jako hodnotu barvy textu přičtenou k šestnáctinásobku hodnoty barvy pozadí
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);
}

Každý výstup na konzoli po zavolání této funkce bude mít zvolenou barvu. K tomu si můžeme vytvořit funkci pro výstup barevného textu:

void colored_cout(int background_color, int foreground_color, const char* text)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << text;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//nastavení původní (základní) barvy
}

Tuhle funkci si můžeme přetížit i pro další datové typy:

void colored_cout(int background_color, int foreground_color, bool value)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << value;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//původní barva
}
void colored_cout(int background_color, int foreground_color, short number)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << number;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//původní barva
}
void colored_cout(int background_color, int foreground_color, int number)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << number;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//původní barva
}
void colored_cout(int background_color, int foreground_color, float number)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << number;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//původní barva
}
void colored_cout(int background_color, int foreground_color, double number)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), background_color*16+foreground_color);//nová barva
    cout << number;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), grey);//původní barva
}

Funkčnost můžeme vyzkoušet například jednoduchým cyklem, který zobrazí všechny možné kombinace barev.

for(int i = 0; i<16; i++)
    for(int j = 0; j<16; j++)
    {
        colored_cout(i, j, i*16+j);
        colored_cout(i, j, " Hello world\n");
    }

Změna titulku konzole

Změny titulku můžeme docílit například takto:

system("Title Text coloring");

Tento způsob by se ale neměl používat (stejně jako system("color 0F") ). Proto použijeme funkci SetConsoleTitle. Té jako parametr předáme nový titulek konzole ve tvaru TEXT("nový titulek") (to kvůli správnému datovému typu).

SetConsoleTitle(TEXT("Text coloring"));

Pozice kurzoru

Pozici v konzoli můžeme měnit pomocí funkce SetConsoleCur­sorPosition. Té předáme jako první parametr GetStdHandle(STD_O­UTPUT_HANDLE) (stejně jako u SetConsoleTex­tAttribute) a jako druhý parametr instanci struktury COORD. Do ní můžeme pozici uložit dvěma způsoby:

COORD pozice = { x, y };
//nebo
COORD pozice;
pozice.X = x;
pozice.Y = y;

Takže funkce pro přesunutí kurzoru by mohla vypadat takhle:

void move_cursor( int x, int y )
{
    COORD pozice = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pozice);
}

Skrytí kurzoru

Na závěr si ještě ukážeme, jak skrýt (nebo zobrazit) kurzor pomocí SetConsoleCur­sorInfo. Ta má stejně jako SetConsoleCur­sorPosition a SetConsoleTex­tAttribute dva parametry:

GetStdHandle(STD_O­UTPUT_HANDLE) a instanci struktury CONSOLE_CURSOR_IN­FO.

void cursor_visible(bool visible)
{
   CONSOLE_CURSOR_INFO info = {100, visible};
   /*nebo
   CONSOLE_CURSOR_INFO info;
   info.dwSize = 100;
   info.bVisible = visible;*/
   SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}

A ještě pár rad na závěr:

  1. Není dobré používat funkci system(). Za prvé je pomalá a za druhé její používání není zrovna přehledné.
  2. Místo neustálého psaní GetStdHandle(STD_O­UTPUT_HANDLE) si můžeme vytvořit proměnnou se stejnými daty:
    HANDLE cHandle = GetStdHandle(STD_O­UTPUT_HANDLE);
    SetConsoleTex­tAttribute(cHan­dle, grey);

 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 320x (19.43 MB)
Aplikace je včetně zdrojových kódů v jazyce C++

 

Všechny články v sekci
Zdrojákoviště C++ - Základní konstrukce
Článek pro vás napsal Zdeněk Pavlátka
Avatar
Uživatelské hodnocení:
5 hlasů
Autor se věnuje spoustě zajímavých věcí ze světa informatiky a grafiky
Aktivity