// - "Talk to me like I'm a 3 year old!" Programming Lessons -
//
// $Author: Ben Humphrey digiben@gametutorials.com
//
// $Program: ColorText
//
// $Description: Displays Color Text in a Console Window.
//
// $Date: 6/22/00
//
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
#include <windows.h> // Нужно подключить этот файл для консольных функций
#include <stdio.h>
/* Это наша функция, которая рисует цветную строку в DOS окне.
Мы просто передаем в нее строку, координаты X и Y, а затем нужный цвет.
Цвет может быть цветом фона и цветом текста. Вот несколько примеров цвета:
FOREGROUND_GREEN; FOREGROUND_RED; FOREGROUND_BLUE; -
BACKGROUND_RED; BACKGROUND_BLUE; BACKGROUND_GREEN;
Вы можете смешивать эти цвета чтобы создавать другие. Вы увидите как это делать в "Main()".
*/
void DrawColorString(char *szText, int X, int Y, WORD color)
{
// Запишем координаты X и Y в структуру.
COORD screenPos={X, Y};
// Создадим указатель на буфер для хранения цвета каждого символа.
WORD *colorBuf=NULL;
// Здесь будет храниться количество символов, выводимых на экран. (Хотя нам оно не понадобится).
DWORD dwResult=0;
// Это переменная буфера вывода. Считайте ее ссылкой на видеокарту.
HANDLE OutputH;
// Здесь будет храниться длина передаваемой строки.
int length=0;
// Эта переменная используется как счетчик.
int i=0;
// Проверка на нулевую строку. Выход из функции, если не было передано никакой строки.
if(szText == NULL)
return;
// Присваиваем переменной буфер вывода.
OutputH = GetStdHandle(STD_OUTPUT_HANDLE);
// Определяем количество символов в строке.
length = strlen(szText);
/* Далее следует то, что называется "динамическое распределение памяти". Так как мы не знаем,
что за строка передается, мы не можем просто создать строку вот так: WORD colorbuf[неизвестно];
Поэтому то, что мы делаем, это создаем указатель, а затем заполняем его в ходе работы программы.
Мы используем функцию malloc(). Вы наверное заметили перед ней странную вещь. (WORD *).
Это называется "преобразование типов". Так как функция malloc возвращает "void *", нам нужно
преобразовать полученную информацию в "WORD *".
Мы можем преобразовывать что угодно. Как например, если вы хотите сохранить число с плавающей
запятой в целочисленной переменной, просто напишите var1 = (int)var2. Если var2 = 1.2, то var1,
будучи целочисленной переменной, равно 1. Остаток отбрасывается.
Параметр для malloc() это количество байтов памяти, которое нужно выделить. Вы можете сказать
"но я не знаю сколько байтов занимает тип WORD". Это можно узнать с помощью функции sizeof().
И после этого, когда мы знаем, сколько байтов в этом типе, нам нужно узнать, сколько переменных
этого типа мы хотим выделить. Так как нам известна длина строки, мы просто умножаем количество
байтов на длину. Итак, sizeof(WORD) * length дает нам количество байтов бамяти, которое необходимо
выделить. Позже мы освобождаем память функцией "free()".
*/
colorBuf = (WORD*)malloc(sizeof(WORD) * length);
/* Теперь мы перемещаемся по буферу цвета и присваиваем цвет для каждого символа.
Указатель на буфер является одномерным массивом, поэтому мы можем использовать квадратные скобки.
Переменная color это параметр, который мы передали в функцию. Мы могли бы написать "colorBuf[i] = rand();"
и каждый символ в строке был бы случайного цвета.
*/
for (i=0; i < length; i++)
{
colorBuf[i] = color;
}
/* Эти функции рисуют текст и цвет текста на экран. Первая рисует цвет. Ее параметрами являются:
(буфер вывода, массив, содержащий цвет для каждого символа, длина строки, положение на экране,
и адрес переменной типа DWORD для сохранения количества выведенных символов).
*/
WriteConsoleOutputAttribute(OutputH, colorBuf, length, screenPos, &dwResult);
/* Следующая функция рисует собственно символы. Ее параметрами являются:
(буфер вывода, строка, которую нужно печатать, длина строки, положение на экране,
и адрес переменной типа DWORD для сохранения количества выведенных символов).
Последний параметр, который нам не нужен, требуется для вызова функции.
*/
WriteConsoleOutputCharacter(OutputH, szText, length, screenPos, &dwResult);
free(colorBuf);
colorBuf = NULL;
/* Так мы освобождаем выделенную память. Всегда следует делать это.
После того, как мы освободили указатель, мы всегда должны установить ему значение NULL.
Проверка, равен ли указатель нулевому значению это способ определить, является ли
указатель "действительным". Если мы не присвоим ему нулевого значения, он будет все еще
указывать на адрес памяти. Однако, если мы попытаемся получить доступ к этой памяти,
программа зависнет. Поэтому всегда присваивайте освобожденным указателям значение NULL.
У вас бывало так, когда вы играете в игру и компьютер через некоторое время замедляет
работу? Или когда после того, как вы выходите из программы, ваш компьютер также работает
медленнее? Это не потому что он устал. Это из-за того, что программисты не освободили
память. Когда у Windows запрашивается память, она закрывает доступ к ней другим программам.
Если вы не освобождаете эту память, компьютер считает, что она все еще используется.
Вам необходимо перезапустить компьютер чтобы получить доступ к ней.
*/
}
void main()
{
// Пишем слово "Red" цветом RED (красный).
DrawColorString("Red", 40, 0, FOREGROUND_RED);
// Пишем слово "White" цветом WHITE (белый).
// Если объединить цвета оператором OR ("|"), получим белый цвет.
DrawColorString("White",40, 1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
// Пишем слово "Blue" цветом BLUE (синий).
DrawColorString("Blue", 40, 2, FOREGROUND_BLUE);
// Пишем "Red" на красном фоне.
DrawColorString("Red", 40, 4, BACKGROUND_RED);
// Пишем "White" на белом фоне.
DrawColorString("White",40, 5, BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
// Пишем "Blue" на синем фоне.
DrawColorString("Blue", 40, 6, BACKGROUND_BLUE);
// Пишем красный текст на зеленом фоне.
DrawColorString("Color Text!", 40, 8, FOREGROUND_RED | BACKGROUND_GREEN);
}
// © 2001 GameTutorials
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
|