本文为转载文档,原文链接:http://blog.csdn.net/bnb45/article/details/8034597
控制文本的移动,可以取代清屏再重绘操作。如果用来做文本编辑器的滚动条是很合适的,也许也可以用在俄罗斯方块上面。控制台使用一个函数把某个区域内的文本移动到另一个区域。
在缓冲区中输出4行字,分别在对应的行上。然后使用移动文本的函数把第三行后面的文本移到第一行后面;
[cpp] view plaincopy
- #include "MyConsole.h"
- #include <stdio.h>
- int main()
- {
- CMyConsole myConsole;
- printf("\n1111111111111111111\n");
- printf("2222222222222222222\n");
- printf("3333333333333333333\n");
- printf("4444444444444444444\n");
- system("pause"); // 暂停
- SMALL_RECT rc = {0, 3, 30, 20}; // 要移动的区域
- myConsole.MoveText(rc, 10, 1); // 移动到坐标(10,1)
- system("pause");
- return 0;
- }
缓冲区的文本移动使用的函数是:ScrollConsoleScreenBuffer,文本中对它的解释如下:
[cpp] view plaincopy
- BOOL ScrollConsoleScreenBuffer(
- HANDLE hConsoleOutput, // 句柄
- CONST SMALL_RECT* lpScrollRectangle, // 要滚动或移动的区域
- CONST SMALL_RECT* lpClipRectangle, // 裁剪区域
- COORD dwDestinationOrigin, // 新的位置
- CONST CHAR_INFO* lpFill // 填充字符
- );
比较容易搞不明白的是第二个参数和第三个参数,它们都是 SMALL_RECT 指针类型。为了说明这个函数的使用方法,教程里还举了另一个函数为例:DeleteLine。它的功能是删除指定行,并将下面的文本上移,例如删除上面例子中的第二行,则1111的下一行变成了3333。
[cpp] view plaincopy
- void DeleteLine(int row)
- {
- SMALL_RECT rcScroll, rcClip;
- COORD crDest = {0, row - 1};
- CHAR_INFO chFill;
- CONSOLE_SCREEN_BUFFER_INFO bInfo;
- GetConsoleScreenBufferInfo( hOut, &bInfo ); // 获取控制台信息
- rcScroll.Left = 0;
- rcScroll.Top = row;
- rcScroll.Right = bInfo.dwSize.X - 1;
- rcScroll.Bottom = bInfo.dwSize.Y - 1; // 设置要滚动的区域
- rcClip = rcScroll; // 设置裁剪区域
- chFill.Attributes = bInfo.wAttributes;
- chFill.Char.AsciiChar = ' '; // 设置要填充的文本和属性
- ScrollConsoleScreenBuffer(hOut, &rcScroll, &rcClip, crDest, &chFill);
- }
上面的一段代码中,滚动区域从要删除的行开始到缓冲区的末尾,裁剪区域和滚动区域一样。然后把这一整块移动到要删除的行的前一行(上移),根据教程的说法,因为向上一行不包括在裁剪区域内,所以不会被更新,也就是消失了,从而达到删除行的目的。从这里可以了解到更多的信息,比如简单如第一参数(句柄),第四参数(目标坐标),第五参数(替换为空,属性为控制台现有属性)。即使这样,对于第二和第三参数的理解仍然不够透彻。接下来以上面的四行输出做两个实验:
滚动区域为第二行到末尾,裁剪区域为第二行和第三行;执行上移一行操作:
第二、三行和第四行都上移了,第二行因为超出裁剪区被裁剪掉,原本的第四行没变。它在裁剪区域外。
滚动区域为第二行到第三行,裁剪区域为第二行到末尾;执行上移一行操作:
第二、三行上移,第二行被裁剪,第三行由参数填充;
- 首先对滚动区域执行移动操作;
- 产生两个画面:移动前画面;移动后画面;
- 裁剪区域内绘制的是移动后画面;
- 裁剪区域外绘制的是移动前画面;
[cpp] view plaincopy
- // ---- 移动文本
- void CMyConsole::MoveText(SMALL_RECT rc, int x, int y)
- {
- COORD crDest = {x, y};
- CHAR_INFO chFill;
- chFill.Attributes = bInfo.wAttributes;
- chFill.Char.AsciiChar = ' ';
- // -- 滚动和移动文本
- // @param HANDLE [in] 句柄
- // @param CONST SMALL_RECT * [in] 要滚动或移动的区域
- // @param CONST SMALL_RECT * [in] 裁剪区域,NULL时为默认整个缓冲区
- // @param COORD [in] 新的位置
- // @param CONST CHAR_INFO [in] 填充字符
- ScrollConsoleScreenBuffer(hOut, &rc, NULL, crDest, &chFill);
- }