您的位置:首页 > 其它

控制台界面控制(七):移动文本

2016-01-07 19:39 344 查看
本文为转载文档,原文链接: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);

}

上面的一段代码中,滚动区域从要删除的行开始到缓冲区的末尾,裁剪区域和滚动区域一样。然后把这一整块移动到要删除的行的前一行(上移),根据教程的说法,因为向上一行不包括在裁剪区域内,所以不会被更新,也就是消失了,从而达到删除行的目的。从这里可以了解到更多的信息,比如简单如第一参数(句柄),第四参数(目标坐标),第五参数(替换为空,属性为控制台现有属性)。即使这样,对于第二和第三参数的理解仍然不够透彻。接下来以上面的四行输出做两个实验:




实验一:滚动区域大于裁剪区域


滚动区域为第二行到末尾,裁剪区域为第二行和第三行;执行上移一行操作:



第二、三行和第四行都上移了,第二行因为超出裁剪区被裁剪掉,原本的第四行没变。它在裁剪区域外。

实验二:裁剪区域大于滚动区域


滚动区域为第二行到第三行,裁剪区域为第二行到末尾;执行上移一行操作:



第二、三行上移,第二行被裁剪,第三行由参数填充;

ScrollConsoleScreenBuffer 结论




首先对滚动区域执行移动操作;
产生两个画面:移动前画面;移动后画面;
裁剪区域绘制的是移动后画面;
裁剪区域绘制的是移动前画面;

文本移动函数

[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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: