Чтение и запись блоков символов и атрибутов

Функция ReadConsoleOutput копирует прямоугольный блок символьных и цветных атрибутов данных из экранного буфера консоли в буфер назначения. Функция рассматривает буфер назначения как двухмерный массив структур CHAR_INFO. Точно так же функция WriteConsoleOutput копирует прямоугольный блок символьных и цветных атрибутов данных из исходного буфера в экранный буфер консоли. Для получения дополнительной информации о чтении или записи в прямоугольных блоках ячеек экранного буфера, см. статью Методы ввода и вывода данных.

Нижеследующий пример использует функцию CreateConsoleScreenBuffer, чтобы создать новый экранный буфер. После того, как функция SetConsoleActiveScreenBuffer сделает этот экранный буфер активным, во временный буфер скопируется блок символов и атрибутов цвета верхних двух строк SDTOUT экранного буфера. Данные далее копируются из временного буфера в новый активный экранный буфер. Когда приложение завершает работу, используя новый экранный буфер, оно вызывает SetConsoleActiveScreenBuffer, чтобы восстановить исходный STDOUT экранный буфер.

Обратите внимание! на то, что MyErrorExit - групповой символ - заместитель для определяемой программой функции, которая показывает на экране и обрабатывает аварийные ситуации.

 
#include <windows.h>

VOID main(void)
{
    HANDLE hStdout, hNewScreenBuffer;
    SMALL_RECT srctReadRect;
    SMALL_RECT srctWriteRect;
    CHAR_INFO chiBuffer[160]; 		// [2][80];
    COORD coordBufSize;
    COORD coordBufCoord;
    BOOL fSuccess;

    // Получим дескриптор STDOUT экранного буфера из которого будем копировать и создадим
    // новый экранный буфер, в который будем копировать.

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    hNewScreenBuffer = CreateConsoleScreenBuffer(
       GENERIC_READ |           	// доступ к чтению/записи
       GENERIC_WRITE,
       0,                       	// совместно не используется
       NULL,                    	// атрибутов защиты нет
       CONSOLE_TEXTMODE_BUFFER,       // должен быть TEXTMODE
       NULL);                   	// зарезервирован, должен быть NULL
    if (hStdout == INVALID_HANDLE_VALUE ||
            hNewScreenBuffer == INVALID_HANDLE_VALUE)
    {
        MyErrorExit("CreateConsoleScreenBuffer");
    }

    // Сделаем новый экранный буфер активным экранным буфером.

    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
        MyErrorExit("SetConsoleActiveScreenBuffer");

    // Установим прямоугольник источника.

    srctReadRect.Top = 0;    // верхний левый: строчка 0, колонка 0
    srctReadRect.Left = 0;
    srctReadRect.Bottom = 1; // нижний правый: строчка 1, колонка 79
    srctReadRect.Right = 79;

    // Размер временного буфера равен 2 строчки x 80 колонок.

    coordBufSize.Y = 2;
    coordBufSize.X = 80;

    // Верхняя левая ячейка назначения временного буфера равна строка 0, колонка 0.

    coordBufCoord.X = 0;
    coordBufCoord.Y = 0;

    // Скопируем блок из экранного буфера во временный буфер.

    fSuccess = ReadConsoleOutput(
       hStdout,        	// экранный буфер, из которого читаем
       chiBuffer,      	// буфер, в который копируем
       coordBufSize,   	// размер колонки/строки chiBuffer
       coordBufCoord,  	// верхняя левая ячейка назначения в chiBuffer
       &srctReadRect); 	// источниковый прямоугольник экранного буфера

    if (! fSuccess)
        MyErrorExit("ReadConsoleOutput");

    // Установим прямоугольник назначения.

    srctWriteRect.Top = 10;    // верхний левый: строка 10, колонка 0
    srctWriteRect.Left = 0;
    srctWriteRect.Bottom = 11; // нижний правый: строка 11, колонка 79
    srctWriteRect.Right = 79;

    // Копируем из временного буфера в новый экранный буфер.

    fSuccess = WriteConsoleOutput(
        hNewScreenBuffer, 	// экранный буфер, в который будем записывать
        chiBuffer,        	// буфер, из которого копируем
        coordBufSize,     	// размер колонки/строки chiBuffer
        coordBufCoord,    	// верхняя левая ячейка источника в chiBuffer
        &srctWriteRect);  	// прямоугольник назначения экранного буфера
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutput");
    Sleep(10000);

    // Восстановление исходного активного экранного буфера.

    if (! SetConsoleActiveScreenBuffer(hStdout))
        MyErrorExit("SetConsoleActiveScreenBuffer");

}

 

Назад в оглавление темы
На главную страницу темы

Hosted by uCoz