Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2013 mgr
Jerzy Wałaszek
|
Biblioteka newconio powstała kilka lat temu na kole informatycznym w I LO w Tarnowie. Jej głównym zastosowaniem jest umożliwienie programiście sterowanie wszystkimi funkcjami dostępnymi w trybie konsoli znakowej Windows bez zbędnego grzebania się w Win32 API:
Funkcje te pozwalają na wygodne pisanie dowolnych gier konsolowych, na których młodzi adepci szlifują swoje umiejętności programowania w języku C++. Na kole informatycznym I LO powstało wiele programów, które wykorzystują bibliotekę newconio.
Instalacja biblioteki jest bardzo prosta:
Przekopiuj do swojego katalogu projektowego poniższe dwa pliki:
newconio.cpp | - | plik źródłowy biblioteki |
newconio.h | - | plik nagłówkowy dla biblioteki |
Dołącz do projektu plik newconio.cpp.
W każdym programie wykorzystującym funkcje biblioteczne wpisz polecenie preprocesora:
#include "newconio.h"
Na początku funkcji main() umieść wywołanie:
_cinit();
Dokonuje ono inicjalizacji biblioteki. Od tego momentu możesz w swoim programie korzystać ze wszystkich funkcji biblioteki. W Code::Blocks możesz zapisać szablon projektu użytkownika, który znakomicie przyspiesza wszystkie te czynności.
Funkcja inicjuje bibliotekę newconio oraz ustawia odpowiednio konsolę znakową do pracy z programem. Funkcję tą wywołujemy tylko jeden raz w programie użytkownika - na samym początku funkcji main():
main() { _cinit(); ... }
Konsola znakowa pracuje w innym standardzie znaków niż środowisko graficzne Windows, w którym przygotowujemy teksty programów C++. Konsekwencją tego faktu jest to, iż teksty zawierające polskie literki będą nieprawidłowo wyświetlone przez konsolę. Problem rozwiązuje funkcja _pl(). Zamienia ona kody znaków reprezentujących polskie literki w standardzie Windows na odpowiednie kody tych znaków w konsoli znakowej. Użycie jest następujące:
... cout << _pl("Zażółć gęślą jaźń\n"); ...
Procedura wyświetla podany tekst na środku zadanego wiersza ekranu. Nadaje się głównie do tytułów.
Funkcja czyści ekran konsoli znakowej. Ustawia pozycję kursora na początku pierwszego wiersza. Na całym ekranie ustawiane są bieżące atrybuty kolorów.
Jeśli tworzymy na ekranie konsoli jakąś animację, to często denerwuje nas kursor tekstowy. Za pomocą tej funkcji możemy go wyłączyć - tzn. kursor tekstowy stanie się niewidoczny.
Po wykonaniu tej funkcji kursor staje się znów widoczny.
Funkcja wstrzymuje wykonanie programu na zadaną liczbę milisekund. Jest przydatna, gdy chcemy zsynchronizować czasowo wykonanie programu. Odmierzanie czasu jest przybliżone i nie należy raczej tworzyć np. zegara na podstawie tej funkcji. Ale w pozostałych przypadkach jest bardzo pożyteczna.
delay(1000); // czeka około 1 sekundę delay(500); // czeka około 1/2 sekundy, itd.
Funkcja wypełnia zadany obszar okna konsoli (od pozycji (xb,yb) w lewym górnym narożniku, do pozycji (xe,ye) w prawym dolnym narożniku) podanym atrybutem. Znaki zawarte w tym obszarze nie są zmieniane. Również nie zmienia się pozycja kursora tekstowego.
fillrectattr(0x2f,1,1,78,23); // prostokąt z ciemnozielonym tłem i białymi znakami
Funkcja wypełnia zadany obszar okna konsoli (od pozycji (xb,yb) w lewym górnym narożniku, do pozycji (xe,ye) w prawym dolnym narożniku) podanym znakiem. Kolory zawarte w tym obszarze nie są zmieniane. Również nie zmienia się pozycja kursora tekstowego.
fillrectch('X',1,1,78,23); // prostokąt wypełniony literkami X
Funkcja wypełnia zadany obszar okna konsoli (od pozycji (xb,yb) w lewym górnym narożniku, do pozycji (xe,ye) w prawym dolnym narożniku) podanym znakiem i atrybutem. Nie zmienia się pozycja kursora tekstowego.
fillrect('X',0x2f,1,1,78,23); // prostokąt wypełniony literkami białymi X na ciemnozielonym tle.
Na obrzeżach zadanego obszaru okna konsoli (od pozycji (xb,yb) w lewym górnym narożniku, do pozycji (xe,ye) w prawym dolnym narożniku) rysowana jest ramka. Nie zmienia się pozycja kursora tekstowego. Rodzaje ramek są następujące:
FRAME_EMPTY | - ramka wypełniona spacjami |
FRAME_SINGLE | - ramka zbudowana z pojedynczej linii |
FRAME_DOUBLE | - ramka zbudowana z linii podwójnej |
FRAME_SOLID | - ramka wypełniona znakiem pełnym |
FRAME_SHADED | - ramka wypełniona znakiem cieniowanym |
Na obrzeżach zadanego obszaru okna konsoli (od pozycji (xb,yb) w lewym górnym narożniku, do pozycji (xe,ye) w prawym dolnym narożniku) rysowana jest ramka. Dodatkowo wnętrze obszaru zostaje wypełnione spacjami i atrybutem koloru. Nie zmienia się pozycja kursora tekstowego. Rodzaje ramek są takie same jak dla funkcji frame().
Funkcja włącza tryb pełnoekranowy dla parametru tryb = true lub tryb pracy w oknie dla tryb = false. W trybie pełnoekranowym okno konsoli posiada 50 wierszy po 80 kolumn w każdym. Ekran nie może być przewijany. W trybie okienkowym liczba kolumn wynosi 80, lecz liczba wierszy może zależeć od ustawionego rozmiaru okna. Treść okna konsoli może być przewijana.
... fullscreen(true); // włączenie trybu pełnoekranowego ... fulscreen(false); // powrót do trybu okienkowego ...
Funkcja odczytuje atrybut koloru z pozycji x,y ekranu konsoli.
Funkcja odczytuje klawisz naciśnięty na klawiaturze. Jeśli klawisz nie został naciśnięty, funkcja oczekuje na niego. Nadaje się zatem np. do wstrzymywania pracy programu aż do reakcji użytkownika.
Jeśli naciśnięto klawisz sterujący (np. klawisze kursora, F1..F12, PgUp, PgDn), to pierwsze wywołanie tej funkcji zwraca 0. Dopiero drugie wywołanie zwraca tzw. kod matrycowy klawisza sterującego. Kody matrycowe znajdziemy w kodzie programu przy definicji tablicy kbdtab[].
... while(!getch()) ; // oczekiwanie na dowolny klawisz. ...
Funkcja odczytuje kod ASCII znaku umieszczonego na pozycji x,y ekranu konsoli.
Funkcja rezerwuje bufor dla zdefiniowanego w parametrach obszaru okna konsoli i umieszcza w tym buforze zawartość obszaru, po czym adres (wskaźnik) bufora jest zwracany jako wynik (jeśli wynikiem jest NULL, to obszar został błędnie zdefiniowany lub jest poza oknem konsoli). Funkcja ta została zaprojektowana do chwilowego przechowania fragmentu ekranu konsoli, na którym wyświetlono coś innego (np. komunikat). Funkcja współpracuje z funkcją putrect(), która odtwarza z bufora poprzednio zapamiętany obszar.
WORD * bufor; ... if(!(bufor = getrect(10,10,69,14)) { ... // robimy coś na obszarze 10,10 \ 69,14, np, wyświetlamy ostrzeżenie putrect(bufor); // odtwarzamy obszar i zwalniamy pamięć bufora }
Funkcja umieszcza kursor na pozycji x,y okna konsoli. Pierwszy zapis do okna rozpocznie się od tej pozycji.
... gotoxy(37,12); cout << "HELLO"; ...
Funkcja rozjaśnia kolor tekstu (o ile nie jest rozjaśniony), który zostanie po niej wypisany w oknie konsoli.
... cout << _pl("Naciśnij klawisz "); highvideo(); cout << "ENTER"; lowvideo(); cout << _pl(", aby zakończyć działanie programu..."); ...
Funkcja sprawdza, czy na klawiaturze został naciśnięty jakiś klawisz. Jeśli tak, zwraca true. Inaczej zwraca false.
... while(!kbhit()) { ... } ...
Funkcja przyciemnia kolor tekstu (o ile nie jest przyciemniony), który zostanie po niej wypisany w oknie konsoli.
... cout << _pl("Naciśnij klawisz "); highvideo(); cout << "ENTER"; lowvideo(); cout << _pl(", aby zakończyć działanie programu..."); ...
Funkcja wprowadza atrybut koloru na pozycję x,y ekranu konsoli. Kolor znaku na tej pozycji oraz jego tła zostaną odpowiednio zmienione.
Funkcja umieszcza znak na pozycji x,y ekranu konsoli. Atrybut tej pozycji nie jest zmieniany.
Funkcja odtwarza obszar konsoli zapamiętany wcześniej za pomocą funkcji getrect(). Użyty do tego celu bufor jest po wykonaniu operacji zwalniany.
Funkcja umieszcza podany znak oraz atrybut koloru na pozycji x,y ekranu konsoli.
Funkcja przesuwa treść obszaru zawartego w prostokącie od (xb,yb) do (xe,ye) w podanym kierunku i na zadaną odległość. Treść okna konsoli poza zdefiniowanym obszarem nie ulega zmianie. Po przesunięciu treści obszaru powstaje puste miejsce. Zostanie ono wypełnione spacjami w bieżącym kolorze tła i tekstu. Dozwolone kierunki przesuwu są następujące:
SCROLL_UP | - przesuw w górę |
SCROLL_RIGHT | - przesuw w prawo |
SCROLL_DOWN | - przesuw w dół |
SCROLL_LEFT | - przesuw w lewo |
Funkcja ustawia bieżący atrybut koloru. Po jej wywołaniu znaki wypisywane na konsoli będą posiadały kolory tekstu i tła zgodne z podanym atrybutem.
Funkcja ustawia kolor tła znaków. Kody kolorów (0...16) podaliśmy w tabelce na początku rozdziału. Zamiast wartości liczbowych można również stosować odpowiednie stałe, np. BLACK, YELLOW, WHITE itp. Po wywołaniu tej funkcji znaki zapisywane do konsoli będą posiadały zadany kolor tła.
Funkcja ustawia kolor znaków. Kody kolorów (0...16) podaliśmy w tabelce na początku rozdziału. Zamiast wartości liczbowych można również stosować odpowiednie stałe, np. BLACK, YELLOW, WHITE itp. Po wywołaniu tej funkcji znaki zapisywane do konsoli będą posiadały zadany kolor.
Funkcja odczytuje numer kolumny ekranu konsoli zawierającej kursor.
Funkcja odczytuje numer wiersza ekranu konsoli zawierającego kursor.
Konsola Windows jest tzw. środowiskiem znakowym. Dostępny ekran zbudowany jest z siatki pól, na których możemy umieszczać znaki oraz określać kolor znaku i kolor jego tła. Ekran podzielony jest na wiersze - w trybie pełnoekranowym (dostępnym po naciśnięciu klawisza lewy-Alt + Enter) jest ich 50. W każdym wierszu możemy umieścić po 80 znaków.
Kolory komórki tekstowej określa tzw. atrybut koloru. Jest to liczba z zakresu od 0 do 255, którą najlepiej rozważać w postaci binarnej. 8 bitów atrybutu dzieli się na dwa 4-ro bitowe pola, które określają osobno kolor tła i kolor tekstu:
kolor tła | kolor liter | ||||||
---|---|---|---|---|---|---|---|
I | R | G | B | I | R | G | B |
b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
Jeśli są ustawione na 1, poszczególne bity atrybutu koloru posiadają następujące znaczenie:
I - rozjaśnienie koloru, tzw. bit
intensywności
R - składowa czerwona (ang. RED)
G - składowa zielona (ang. GREEN)
B - składowa niebieska (ang. BLUE)
Na przykład chcemy uzyskać ciemnoniebieskie tło i znaki żółte. Zatem atrybut kolory będzie posiadał ustawione bity:
00011110(2) = 0x1e;
Obok podajemy kod szesnastkowy atrybutu. Do określania atrybutów kolorów lepiej jest stosować system szesnastkowy niż dziesiętny.
4-ro bitowe kody kolorów są następujące:
binarnie | szesnastkowo | dziesiętnie | stała | kolor |
---|---|---|---|---|
0000 | 0 | 0 | BLACK | |
0001 | 1 | 1 | BLUE | |
0010 | 2 | 2 | GREEN | |
0011 | 3 | 3 | CYAN | |
0100 | 4 | 4 | RED | |
0101 | 5 | 5 | MAGENTA | |
0110 | 6 | 6 | BROWN | |
0111 | 7 | 7 | LIGHTGRAY | |
1000 | 8 | 8 | DARKGRAY | |
1001 | 9 | 9 | LIGHTBLUE | |
1010 | A | 10 | LIGHTGREEN | |
1011 | B | 11 | LIGHTCYAN | |
1100 | C | 12 | LIGHTRED | |
1101 | D | 13 | LIGHTMAGENTA | |
1110 | E | 14 | YELLOW | |
1111 | F | 15 | WHITE |
Fragment ekranu jednego z
pierwszych komputerów IBM-XT pracującego w trybie znakowym |
---|
Można zastanawiać się po co w graficznym środowisku Windows istnieje taki twór jak konsola znakowa? Powodów należy szukać w historii komputerów. Na samym początku nie istniały karty graficzne (lub były tak drogie, iż zwykły użytkownik mógł sobie o nich jedynie pomarzyć, coś o tym wiem). Komputery wyposażano w proste interfejsy znakowe. W trybie znakowym komputer obsługuje dużo mniej informacji - a pierwsze komputery nie były specjalnie szybkie.
Policzmy: na ekranie konsoli mamy 50 wierszy po 80 znaków i atrybutów, co daje w sumie:
50 x (80 + 80) = 8000 B, czyli około 8KB.
Dla porównania współczesny ekran graficzny Windows pracuje w rozdzielczości 1280 x 1024 pikseli (a często większej), co daje 1310720 pikseli. Każdy piksel reprezentowany jest w pamięci komputera przez 4 bajty (przechowują informacje o kolorze punktu), zatem w sumie mamy:
1310720 x 4 = 5242880 B, czyli 5120 KB
A to jest 640 razy więcej informacji niż w przypadku ekranu konsoli. Wyjaśnia to zatem początkową popularność rozwiązań tekstowych - wolne komputery lepiej radziły sobie z mniejszą ilością wyświetlanych informacji. Z drugiej strony karta tekstowa była o niebo prostsza od karty graficznej, co wiązało się z niższą ceną, zatem większą popularnością wśród pierwszych użytkowników komputerów IBM PC.
Tryb tekstowy jest do dzisiaj obecny we wszystkich nowoczesnych kartach graficznych - właśnie naciskając w oknie konsoli kombinację klawiszy lewy Alt + Enter powodujemy przejście w ten tryb pracy. Grafika znika, a na ekranie widzimy tylko litery.
Konsola posiada wiele zalet dla początkującego programisty (i nie tylko, profesjonaliści też często piszą dla niej programy). Po pierwsze program posiada całkowitą kontrolę nad swoim wykonaniem. Po drugie nie musi współpracować z systemem operacyjnym w takim stopniu, jak ma to miejsce w środowisku graficznym Windows. Zatem struktura programu jest o wiele prostsza. Dlatego początkujący programiści zaczynają poznawanie tajników programowania właśnie od trybu znakowego.
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe