Lectura y escritura de bloques de caracteres y atributos

Importante

En este documento se describe funcionalidad de la plataforma de consola que ya no forma parte de nuestro plan de desarrollo del ecosistema. No se recomienda usar este contenido en nuevos productos, pero seguiremos admitiendo los usos existentes para el futuro indefinido. Nuestra solución moderna preferida se centra en secuencias de terminal virtual para lograr la máxima compatibilidad en escenarios multiplataforma. Puede encontrar más información sobre esta decisión de diseño en nuestro documento de Comparación de consola clásica y terminal virtual.

La función ReadConsoleOutput copia un bloque rectangular de datos de atributos de colores y caracteres de un búfer de pantalla de consola en un búfer de destino. La función trata el búfer de destino como una matriz bidimensional de estructuras CHAR_INFO. Del mismo modo, la función WriteConsoleOutput copia un bloque rectangular de datos de atributos de colores y caracteres de un búfer de origen en un búfer de pantalla de consola. Para obtener más información sobre cómo leer o escribir en bloques rectangulares de celdas de búfer de pantalla, consulte Métodos de entrada y salida.

En el ejemplo siguiente se utiliza la función CreateConsoleScreenBuffer para crear un nuevo búfer de pantalla. Después de que la función SetConsoleActiveScreenBuffer active este búfer de pantalla, se copia un bloque de atributos de colores y caracteres de las dos primeras filas del búfer de pantalla STDOUT en un búfer temporal. A continuación, los datos se copian del búfer temporal en el nuevo búfer de pantalla activo. Cuando la aplicación deje de utilizar el nuevo búfer de pantalla, llamará a SetConsoleActiveScreenBuffer para restaurar el búfer de pantalla STDOUT original.

#include <windows.h>
#include <stdio.h>

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

    // Get a handle to the STDOUT screen buffer to copy from and
    // create a new screen buffer to copy to.

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    hNewScreenBuffer = CreateConsoleScreenBuffer(
       GENERIC_READ |           // read/write access
       GENERIC_WRITE,
       FILE_SHARE_READ |
       FILE_SHARE_WRITE,        // shared
       NULL,                    // default security attributes
       CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
       NULL);                   // reserved; must be NULL
    if (hStdout == INVALID_HANDLE_VALUE ||
            hNewScreenBuffer == INVALID_HANDLE_VALUE)
    {
        printf("CreateConsoleScreenBuffer failed - (%d)\n", GetLastError());
        return 1;
    }

    // Make the new screen buffer the active screen buffer.

    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
    {
        printf("SetConsoleActiveScreenBuffer failed - (%d)\n", GetLastError());
        return 1;
    }

    // Set the source rectangle.

    srctReadRect.Top = 0;    // top left: row 0, col 0
    srctReadRect.Left = 0;
    srctReadRect.Bottom = 1; // bot. right: row 1, col 79
    srctReadRect.Right = 79;

    // The temporary buffer size is 2 rows x 80 columns.

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

    // The top left destination cell of the temporary buffer is
    // row 0, col 0.

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

    // Copy the block from the screen buffer to the temp. buffer.

    fSuccess = ReadConsoleOutput(
       hStdout,        // screen buffer to read from
       chiBuffer,      // buffer to copy into
       coordBufSize,   // col-row size of chiBuffer
       coordBufCoord,  // top left dest. cell in chiBuffer
       &srctReadRect); // screen buffer source rectangle
    if (! fSuccess)
    {
        printf("ReadConsoleOutput failed - (%d)\n", GetLastError());
        return 1;
    }

    // Set the destination rectangle.

    srctWriteRect.Top = 10;    // top lt: row 10, col 0
    srctWriteRect.Left = 0;
    srctWriteRect.Bottom = 11; // bot. rt: row 11, col 79
    srctWriteRect.Right = 79;

    // Copy from the temporary buffer to the new screen buffer.

    fSuccess = WriteConsoleOutput(
        hNewScreenBuffer, // screen buffer to write to
        chiBuffer,        // buffer to copy from
        coordBufSize,     // col-row size of chiBuffer
        coordBufCoord,    // top left src cell in chiBuffer
        &srctWriteRect);  // dest. screen buffer rectangle
    if (! fSuccess)
    {
        printf("WriteConsoleOutput failed - (%d)\n", GetLastError());
        return 1;
    }
    Sleep(5000);

    // Restore the original active screen buffer.

    if (! SetConsoleActiveScreenBuffer(hStdout))
    {
        printf("SetConsoleActiveScreenBuffer failed - (%d)\n", GetLastError());
        return 1;
    }

    return 0;
}