【C语言】控制台窗口图形界面编程(五):文本移动

00. 目录

01. CHAR_INFO结构

指定Unicode或ANSI字符及其属性。控制台功能使用此结构来读取和写入控制台屏幕缓冲区。

类型声明

typedef struct _CHAR_INFO {
  union {
    WCHAR UnicodeChar;
    CHAR  AsciiChar;
  } Char;
  WORD  Attributes;
} CHAR_INFO, *PCHAR_INFO;

UnicodeChar
屏幕缓冲区字符单元格的Unicode字符。

AsciiChar
屏幕缓冲区字符单元格的ANSI字符。

Attributes

字符属性。该成员可以是零或以下值的任意组合。

含义
FOREGROUND_BLUE 0x0001 文字颜色包含蓝色。
FOREGROUND_GREEN 0x0002 文字颜色包含绿色。
FOREGROUND_RED 0x0004 文字颜色包含红色。
FOREGROUND_INTENSITY 0x0008 文字颜色加强。
BACKGROUND_BLUE 0x0010 背景颜色包含蓝色。
BACKGROUND_GREEN 0x0020 背景颜色包含绿色。
BACKGROUND_RED 0x0040 背景颜色包含红色。
BACKGROUND_INTENSITY 0x0080 背景颜色加剧。
COMMON_LVB_LEADING_BYTE 0x0100 前导字节。
COMMON_LVB_TRAILING_BYTE 0x0200 尾随字节。
COMMON_LVB_GRID_HORIZONTAL 0x0400 顶部水平
COMMON_LVB_GRID_LVERTICAL 0x0800 左垂直。
COMMON_LVB_GRID_RVERTICAL 0x1000 正确的垂直。
COMMON_LVB_REVERSE_VIDEO 0x4000 反转前景和背景属性。
COMMON_LVB_UNDERSCORE 0x8000 下划线。

02. ScrollConsoleScreenBuffer函数

在屏幕缓冲区中移动数据块。通过指定剪切矩形可以限制移动的效果,因此剪切矩形外部的控制台屏幕缓冲区的内容不会改变。

函数声明:

BOOL WINAPI ScrollConsoleScreenBuffer(
  _In_           HANDLE     hConsoleOutput,
  _In_     const SMALL_RECT *lpScrollRectangle,
  _In_opt_ const SMALL_RECT *lpClipRectangle,
  _In_           COORD      dwDestinationOrigin,
  _In_     const CHAR_INFO  *lpFill
);

功能:
    在屏幕缓冲区中移动数据块
    
参数:
    hConsoleOutput 控制台屏幕缓冲区的句柄。句柄必须具有GENERIC_READ访问权限。
    lpScrollRectangle 指定要移动的控制台屏幕缓冲区矩形的左上角和右下角坐标。
    lpClipRectangle 指定受滚动影响的控制台屏幕缓冲区矩形的左上角和右下角坐标。该指针可以为NULL。
    dwDestinationOrigin 它以字符为单位指定lpScrollRectangle内容新位置的左上角。
    lpFill 指向CHAR_INFO结构的指针,该结构指定在填充lpScrollRectangle和lpClipRectangle交集中的单元格时使用的字符和颜色属性,这些属性由于移动而保留为空。

返回值:
    如果函数成功,则返回值为非零值。
    如果函数失败,则返回值为零。要获取扩展错误信息,请调用GetLastError。

官方参考手册: https://docs.microsoft.com/en-us/windows/console/char-info-str

03. 程序示例

参考代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include <Windows.h>
#include <conio.h>


int main()
{
    //定义句柄变量
    HANDLE hOut = NULL;

    //定义窗口信息变量
    CONSOLE_SCREEN_BUFFER_INFO screenInfo;

    //定义移动区域
    SMALL_RECT scroll;

    //移动位置
    COORD pos = {8, 8};

    //定义填充字符
    CHAR_INFO chFill;


    //获取标准输出句柄
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    //获取窗口信息
    GetConsoleScreenBufferInfo(hOut, &screenInfo);

    chFill.Char.AsciiChar = ' ';
    chFill.Attributes = screenInfo.wAttributes;

    //输出字符串
    printf("AAAAAAAAAAAAAAAAAAAAAAAAA\n");
    printf("BBBBBBBBBBBBBBBBBBBBBBBBB\n");
    printf("CCCCCCCCCCCCCCCCCCCCCCCCC\n");
    printf("DDDDDDDDDDDDDDDDDDDDDDDDD\n");

    //设置移动的区域
    scroll.Left = 2;
    scroll.Top = 2;
    scroll.Right = 20;
    scroll.Bottom = 4;

    //设置文本移动
    ScrollConsoleScreenBuffer(hOut, &scroll, NULL, pos, &chFill);

    getchar();

    //关闭句柄
    CloseHandle(hOut);

    system("pause");
    return 0;
}

执行结果

【C语言】控制台窗口图形界面编程(五):文本移动

参考网址: https://blog.csdn.net/JZQT_T/article/details/30602349

04. 官方参考程序

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

int main(void)
{
    HANDLE hStdout;
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    SMALL_RECT srctScrollRect, srctClipRect;
    CHAR_INFO chiFill;
    COORD coordDest;
    int i;

    printf("\nPrinting 20 lines for reference. ");
    printf("Notice that line 6 is discarded during scrolling.\n");
    for (i = 0; i <= 20; i++)
        printf("%d\n", i);

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    if (hStdout == INVALID_HANDLE_VALUE)
    {
        printf("GetStdHandle failed with %d\n", GetLastError());
        return 1;
    }

    // Get the screen buffer size. 

    if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
    {
        printf("GetConsoleScreenBufferInfo failed %d\n", GetLastError());
        return 1;
    }

    // The scrolling rectangle is the bottom 15 rows of the 
    // screen buffer. 

    srctScrollRect.Top = csbiInfo.dwSize.Y - 16;
    srctScrollRect.Bottom = csbiInfo.dwSize.Y - 1;
    srctScrollRect.Left = 0;
    srctScrollRect.Right = csbiInfo.dwSize.X - 1;

    // The destination for the scroll rectangle is one row up. 

    coordDest.X = 0;
    coordDest.Y = csbiInfo.dwSize.Y - 17;

    // The clipping rectangle is the same as the scrolling rectangle. 
    // The destination row is left unchanged. 

    srctClipRect = srctScrollRect;

    // Fill the bottom row with green blanks. 

    chiFill.Attributes = BACKGROUND_GREEN | FOREGROUND_RED;
    chiFill.Char.AsciiChar = (char)' ';

    // Scroll up one line. 

    if (!ScrollConsoleScreenBuffer(
        hStdout,         // screen buffer handle 
        &srctScrollRect, // scrolling rectangle 
        &srctClipRect,   // clipping rectangle 
        coordDest,       // top left destination cell 
        &chiFill))       // fill character and color
    {
        printf("ScrollConsoleScreenBuffer failed %d\n", GetLastError());
        return 1;
    }

    getchar();

    system("pause");
    return 0;
}

【C语言】控制台窗口图形界面编程(五):文本移动

上一篇:C++ 函数重载并不实用


下一篇:effective c++ 条款6 如果不想要就要告诉大家