控制台界面控制(七):移动文本
2016-01-07 19:39
344 查看
本文为转载文档,原文链接:http://blog.csdn.net/bnb45/article/details/8034597
控制文本的移动,可以取代清屏再重绘操作。如果用来做文本编辑器的滚动条是很合适的,也许也可以用在俄罗斯方块上面。控制台使用一个函数把某个区域内的文本移动到另一个区域。
[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;
}
[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 结论
首先对滚动区域执行移动操作;
产生两个画面:移动前画面;移动后画面;
裁剪区域内绘制的是移动后画面;
裁剪区域外绘制的是移动前画面;
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);
}
控制文本的移动,可以取代清屏再重绘操作。如果用来做文本编辑器的滚动条是很合适的,也许也可以用在俄罗斯方块上面。控制台使用一个函数把某个区域内的文本移动到另一个区域。
效果
在缓冲区中输出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] viewplaincopy
// ---- 移动文本
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);
}
相关文章推荐
- Hibernate注释大全
- IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern
- 19: 津津的储蓄计划(1.5)
- win10切换全角/半角
- <<梦断代码>>阅读笔记二
- <<梦断代码>>阅读笔记一
- Linux下的注释问题
- 无线网络嗅探工具Kismet
- python编写windows平台下脚本二三事
- 双击打开某张表的时候很慢的解决办法
- C和C++内存管理详解
- Ubuntu 12.04全局菜单开启和关闭
- 控制台界面控制(六):边框
- 2599: [IOI2011]Race 点分治
- phpExcel 读取和导出
- BZOJ 1509: [NOI2003]逃学的小孩
- <<浪潮之巅>>阅读笔记三
- [leetcode] 303. Range Sum Query - Immutable
- CoreData
- NSTimer与RunLoop的具体问题分析