没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
控制台窗口界面编程控制
〇、摘要
一、概述
二、控制台文本窗口的一般控制步骤
三、控制台窗口操作
四、文本属性操作
五、文本输出
六、文本操作示例
七、滚动和移动
八、光标操作
九、读取键盘信息
十、读取鼠标信息
十一、结语
补充篇 -- 经典程序( Internet 资源)
摘要:
文本界面的控制台应用程序开发是深入学习 C++、掌握交互系统的实现方法的最简单的
一种手段。然而, Visual C++ 的 C++专用库却没有 TC所支持的文本 ( 字符 ) 屏幕控制函数,
为此本系列文章从一般控制步骤、控制台窗口操作、文本 ( 字符 ) 控制、 滚动和移动光标、键
盘和鼠标等几个方面讨论控制台窗口界面的编程控制方法。
在众多 C++开发工具中,由于 Microsoft 本身的独特优势,选用 Visual C++ 已越来越
被众多学习者所接受。显然,现今如果还再把 TC作为开发环境的话,不仅没有必要,而且
也不利于向 Windows 应用程序开发的过渡。然而, Visual C++ 的 C++专用库却没有 TC所支
持的文本屏幕 ( 控制台窗口 ) 控制函数 (相应的头文件是 conio.h) 。这必然给 C++学习者在文
本界面设计和编程上带来诸多不便。要知道,文本界面设计是一种深入学习 C++、掌握交互
系统的实现方法的最简单的一种手段,它不像 C++的 Windows图形界面应用 程序,涉及知
识过多。为此,本系列文章来讨论在 Visual C++ 6.0 开发环境中,如何编写具有美观清晰
的控制台窗口界面的 C++应用程序。
(一) 概述操作
所谓控制台应用程序, 就是指那些需要与传统 DOS操作系统保持某种程序的兼容, 同时
又不需要为用户提供完善界面的程序。 简单地讲,就是指在 Windows 环境下运行的 DOS程序。
一旦控制台应用程序在 Windows操作系统中运行后,就会弹出一个窗口。例如下列代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("Hello, Console!");
return 0;
}
单击小型编译工具栏中的 “Build ”按钮或按 F7 键,系统出现一个对话框,询问是否将
此项目的工作文件夹设定源文件所在的文件夹,单击 [ 是] 按钮,系统开始编译。 单击小型
编译工具栏中的 “Execute Program”按钮或按 Ctrl+F5 键,运行刚才的程序。 程序运行后,
弹出下图的窗口 :
这就是控制台窗口,与传统的 DOS屏幕窗口相比最主要的区别有:
(1) 默认的控制台窗口有系统菜单和标题, 它是一个内存缓冲区窗口, 缓冲区大小取决
于 Windows操作系统的分配; 而 DOS屏幕是一种物理窗口, 不具有 Windows窗口特性, 其大
小取决于 ROM BIOS分配的内存空间。
(2) 控制台窗口的文本操作是调用低层的 Win32 APIs ,而 DOS屏幕的文本操作是通过
调用 BIOS的 16(10h) 中断而实现的。
(3) 默认的控制台窗口可以接收键盘和鼠标的输入信息, 设备驱动由 Windows管理, 而
DOS屏幕窗口接收鼠标时需要调用 33h 中断,且鼠标设备驱动程序由自己安装。
( 二) 控制台文本窗口的一般控制步骤
在 Visual C++ 6.0 中,控制台窗口界面的一般编程控制步骤如下:调用 GetStdHandle
获取当前的标准输入 (STDIN) 和标准输出 (STDOUT)设备句柄。函数原型为:
HANDLE GetStdHandle( DWORD nStdHandle );
其中, nStdHandle 可以是 STD_INPUT_HANDLE(标准输入设备句柄 ) 、
STD_OUTPUT_HANDLE(标准输出设备句柄 )和 STD_ERROR_HANDLE(标准错误句柄 ) 。
需要说明的是,“句柄”是 Windows最常用的概念。它通常用来标识 Windows 资源 ( 如
菜单、 图标、窗口等 ) 和设备等对象。虽然可以把句柄理解为是一个指针变量类型,但它不
是对象所在的地址指针,而是作为 Windows系统内部表的索引值来使用 的。调用相关文本
界面控制的 API 函数。这些函数可分为三类。一是用于控制台窗口操作的函数 ( 包括窗口的
缓冲区大小、窗口前景字符和背景颜色、窗口标题、大小和位置等 ) ;二是用于控制台输入
输出的函数 ( 包括字符属性操作函数 ) ;其他的函数并为最后一类。 调用 CloseHandle() 来
关闭输入输出句柄。 注意,在程序中还必须包含头文件 windows.h 。下面看一个程序:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
HANDLE hOut;
CONSOLE_SCREEN_BUFFER_INFO bInfo; // 存储窗口信息
COORD pos = {0, 0};
// 获取标准输出设备句柄
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 获取窗口信息
GetConsoleScreenBufferInfo(hOut, &bInfo );
printf("\n\nThe soul selects her own society\n");
printf("Then shuts the door\n");
printf("On her devine majority\n");
printf("Obtrude no more\n\n");
_getch();
// 向窗口中填充字符以获得清屏的效果
FillConsoleOutputCharacter(hOut,' ', bInfo.dwSize.X * bInfo.dwSize.Y, pos,
NULL);
// 关闭标准输出设备句柄
CloseHandle(hOut);
return 0;
}
程序中, COORD和 CONSOLE_SCREEN_BUFFER_ INFO是 wincon.h 定义的控制台结构体类
型,其原型如下:
// 坐标结构体
typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD;
// 控制台窗口信息结构体
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize; // 缓冲区大小
COORD dwCursorPosition; // 当前光标位置
WORD wAttributes; // 字符属性
SMALL_RECT srWindow; // 当前窗口显示的大小和位置
COORD dwMaximumWindowSize; // 最大的窗口缓冲区大小
} CONSOLE_SCREEN_BUFFER_INFO ;
还需要说明的是,虽然在 C++中, iostream.h 定义了 cin 和 cout 的标准输入和输出流
对象。但它们只能实现基本的输入输出 操作,对于控制台窗口界面的控制却无能为力,而
且不能与 stdio.h 和 conio.h 友好相处, 因为 iostream.h 和它们是 C++两套不同的输入 输
出操作方式,使用时要特别注意。
( 三 ) 控制台窗口操作操作
用于控制台窗口操作的 API 函数如下:
GetConsoleScreenBufferInfo 获取控制台窗口信息
GetConsoleTitle 获取控制台窗口标题
ScrollConsoleScreenBuffer 在缓冲区中移动数据块
SetConsoleScreenBufferSize 更改指定缓冲区大小
SetConsoleTitle 设置控制台窗口标题
SetConsoleWindowInfo 设置控制台窗口信息
此外,还有窗口字体、显示模式等控制函数,这里不再细说。下列举一个示例,程序如
下:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
char strTitle[255];
CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息
COORD size = {80, 25};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄
GetConsoleScreenBufferInfo(hOut, &bInfo ); // 获取窗口缓冲区信息
GetConsoleTitle(strTitle, 255); // 获取窗口标题
printf(" 当前窗口标题是: \n%s\n", strTitle);
_getch();
SetConsoleTitle(" 控制台窗口操作 "); // 设置窗口标题
GetConsoleTitle(strTitle, 255);
printf(" 当前窗口标题是: \n%s\n", strTitle);
_getch();
SetConsoleScreenBufferSize(hOut,size); // 重新设置缓冲区大小
_getch();
SMALL_RECT rc = {0,0, 80-1, 25-1}; // 重置窗口位置和大小
SetConsoleWindowInfo(hOut,true ,&rc);
CloseHandle(hOut); // 关闭标准输出设备句柄
return 0;
}
需要说明的是,控制台窗口的原点坐标是 (0, 0) ,而最大的坐标是缓冲区大小减 1,例
如当缓冲区大小为 80*25 时,其最大的坐标是 (79, 24) 。
( 四) 文本属性操作操作
与 DOS字符相似, 控制台窗口中的字符也有相应的属性。 这些属性分为: 文本的前景色、
背景色和双字节字符集 (DBCS)属性三种。 事实上, 我们最关心是文本颜色, 这样可以构造出
美观的界面。颜色属性都是一些预定义标识:
FOREGROUND_BLUE 蓝色
FOREGROUND_GREEN 绿色
FOREGROUND_RED 红色
FOREGROUND_INTENSITY 加强
BACKGROUND_BLUE 蓝色背景
BACKGROUND_GREEN 绿色背景
BACKGROUND_RED 红色背景
BACKGROUND_INTENSITY 背景色加强
COMMON_LVB_REVERSE_VIDEO 反色
与文本属性相关的主要函数有:
BOOL FillConsoleOutputAttribute( // 填充字符属性
HANDLE hConsoleOutput, // 句柄
WORD wAttribute, // 文本属性
DWORD nLength, // 个数
COORD dwWriteCoord, // 开始位置
LPDWORD lpNumberOfAttrsWritten // 返回填充的个数
);
BOOL SetConsoleTextAttribute( // 设置 WriteConsole 等函数的字符属性
HANDLE hConsoleOutput, // 句柄
WORD wAttributes // 文本属性
);
BOOL WriteConsoleOutputAttribute( // 在指定位置处写属性
HANDLE hConsoleOutput, // 句柄
CONST WORD *lpAttribute, // 属性
DWORD nLength, // 个数
COORD dwWriteCoord, // 起始位置
LPDWORD lpNumberOfAttrsWritten // 已写个数
);
另外,获取当前控制台窗口的文本属性是通过调用函数 GetConsoleScreenBufferInfo
后,在 CONSOLE_SCREEN_ BUFFER_INFO结构成员 wAttributes 中得到。
(五) 文本输出
操作文本输出函数有:
BOOL FillConsoleOutputCharacter( // 填充指定数据的字符
HANDLE hConsoleOutput, // 句柄
TCHAR cCharacter, // 字符
DWORD nLength, // 字符个数
COORD dwWriteCoord, // 起始位置
LPDWORD lpNumberOfCharsWritten // 已写个数
);
BOOL WriteConsole( // 在当前光标位置处插入指定数量的字符
HANDLE hConsoleOutput, // 句柄
CONST VOID *lpBuffer, // 字符串
DWORD nNumberOfCharsToWrite, // 字符个数
LPDWORD lpNumberOfCharsWritten, // 已写个数
LPVOID lpReserved // 保留
);
BOOL WriteConsoleOutput( // 向指定区域写带属性的字符
HANDLE hConsoleOutput, // 句柄
CONST CHAR_INFO *lpBuffer, // 字符数据区
COORD dwBufferSize, // 数据区大小
COORD dwBufferCoord, // 起始坐标
PSMALL_RECT lpWriteRegion // 要写的区域
);
BOOL WriteConsoleOutputCharacter( // 在指定位置处插入指定数量的字符
HANDLE hConsoleOutput, // 句柄
LPCTSTR lpCharacter, // 字符串
DWORD nLength, // 字符个数
COORD dwWriteCoord, // 起始位置
LPDWORD lpNumberOfCharsWritten // 已写个数
);
可以看出: WriteConsoleOutput 函数功能相当于 SetConsoleTextAttribute 和
WriteConsole 的功能。而 WriteConsoleOutputCharacter 函数相当于
SetConsoleCursorPosition( 设置光标位置 ) 和 WriteConsole 的功能。 不过在具体使用要注
意它们的区别。
( 六) 文本操作示例操作
下面看一个示例程序:
// 在具有阴影效果的窗口中显示一行字符
#include <windows.h>
HANDLE hOut;
void ShadowWindowLine(char *str);
void DrawBox(bool bSingle, SMALL_RECT rc); // 绘制边框
int main(void)
{
hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄
SetConsoleOutputCP(437); // 设置代码页,这里如果设置成 936(简体中文),
那么程序会怎样?那样的话,将画不出边框。
ShadowWindowLine("Display a line of words, and center the window with
shadow.");
CloseHandle(hOut); // 关闭标准输出设备句柄
return 0;
}
void ShadowWindowLine(char *str)
{
SMALL_RECT rc;
CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息
WORD att0,att1,attText;
int i, chNum = strlen(str);
GetConsoleScreenBufferInfo( hOut, &bInfo ); // 获取窗口缓冲区信息
// 计算显示窗口大小和位置
rc.Left = (bInfo.dwSize.X - chNum)/2 - 2;
rc.Top = 8; // 原代码段中此处为 bInfo.dwSize.Y/2 - 2 ,但是如果您的 DOS屏
幕有垂直滚动条的话,还需要把滚动条下拉才能看到 , 为了方便就把它改为 10
rc.Right = rc.Left + chNum + 4;
rc.Bottom = rc.Top + 4;
att0 = BACKGROUND_INTENSITY; // 阴影属性
att1 = FOREGROUND_RED |FOREGROUND_GREEN |FOREGROUND_BLUE |
FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE;// 文本属性
attText = FOREGROUND_RED |FOREGROUND_INTENSITY; // 文本属性
// 设置阴影然后填充
剩余23页未读,继续阅读
资源评论
沧海一笑-dj
- 粉丝: 3w+
- 资源: 328
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功