今天学习的控制台API的整理还有各种结构体和控制台程序设计的相关信息,emmm整理了好长时间。。。
学习资料
http://www.cnblogs.com/tocy/p/Console-Introduction.html
http://www.cnblogs.com/tocy/p/console_intro_sample.html
http://www.cnblogs.com/tocy/p/console_io_function_intro.html
http://www.cnblogs.com/tocy/category/630597.html
控制台程序处理事件基本流程
1.获取输入输出句柄
2.读取控制台输入
3.判断事件类型
4.处理事件
5.关闭句柄
结构体及类型说明
DWORD unsigned long类型
HANDLE void*指针
WORD unsigned short
COORD 坐标
typedef struct _SMALL_RECT {
SHORT Left;
SHORT Top;
SHORT Right;
SHORT Bottom;
} SMALL_RECT, *PSMALL_RECT;
CONSOLE_CURSOR_INFO 用于存放控制光标信息
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
//光标大小,1-100的值
BOOL bVisible;
//bVisible:光标是否可见
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
CONSOLE_SCREEN_BUFFER_INFO 控制台屏幕缓冲信息
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize;
// 屏幕缓冲区的以字符为单位的宽度(X)和高度(Y)。
COORD dwCursorPosition;
// 光标在屏幕缓冲区的坐标。
WORD wAttributes;
// 绘制文本、背景的颜色等属性,在调用输出函数输出到控制台的时候就会作用
SMALL_RECT srWindow;
// 控制台窗口左上角和右下角对应屏幕缓冲区的位置。该参数可以指定要输出的特定屏幕缓冲区的矩形区域。
COORD dwMaximumWindowSize;
// 控制台窗口以字符为单位的最大宽度和高度。
} CONSOLE_SCREEN_BUFFER_INFO ;
API
获取句柄API
HANDLE GetStdHandle(DWORD nStdHandle);
返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出 /错误的屏幕缓冲区的句柄。其参数nStdHandle的值为下面几种类型的一种:
STD_INPUT_HANDLE 标准输入的句柄
STD_OUTPUT_HANDLE 标准输出的句柄
STD_ERROR_HANDLE 标准错误的句柄
设置属性API
BOOL SetConsoleTextAttribute(
HANDLE hConsoleOutput,
// 使用GetStdHandle取得的句柄
WORD wAttributes
// 设置文本、背景色
);
wAttributes可以取下面的值:
FOREGROUND_BLUE Text color contains blue.
FOREGROUND_GREEN Text color contains green.
FOREGROUND_RED Text color contains red.
FOREGROUND_INTENSITY Text color is intensified.
BACKGROUND_BLUE Background color contains blue.
BACKGROUND_GREEN Background color contains green.
BACKGROUND_RED Background color contains red.
BACKGROUND_INTENSITY Background color is intensified.
COMMON_LVB_LEADING_BYTE Leading byte.
COMMON_LVB_TRAILING_BYTE Trailing byte.
COMMON_LVB_GRID_HORIZONTAL Top horizontal.
COMMON_LVB_GRID_LVERTICAL Left vertical.
COMMON_LVB_GRID_RVERTICAL Right vertical.
COMMON_LVB_REVERSE_VIDEO Reverse foreground and background attributes.
COMMON_LVB_UNDERSCORE Underscore.
SetConsoleCursorInfo设置光标的信息
BOOL SetConsoleCursorInfo(
HANDLE hConsoleOutput,
// 使用GetStdHandle取得的句柄
CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
// 光标信息
);
SetConsoleCursorPosition设置光标位置
BOOL SetConsoleCursorPosition(
HANDLE hConsoleOutput,
COORD dwCursorPosition
);
SetConsoleTitle设置控制台的标题
BOOL SetConsoleTitle(
LPCTSTR lpConsoleTitle
);
SetConsoleActiveScreenBuffer设置活动屏幕缓冲区
BOOL SetConsoleActiveScreenBuffer(
HANDLE hConsoleOutput
);
获取属性API
GetConsoleScreenBufferInfo取得控制台屏幕缓冲信息
BOOL GetConsoleScreenBufferInfo(
HANDLE hConsoleOutput,
PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
);
读写API
ReadConsoleInput来获取输入事件
BOOL ReadConsoleInput(
HANDLE hConsoleInput, //输入句柄
PINPUT_RECORD lpBuffer,//输入事件结构体的指针
DWORD nLength, //要读取的记录数
LPDWORD lpNumberOfEventsRead //用来接受成功读取记录数的指针
);
FillConsoleOutputCharacter 填充指定数据的字符
BOOL FillConsoleOutputCharacter(
HANDLE hConsoleOutput, // 句柄
TCHAR cCharacter, // 字符
DWORD nLength, // 字符个数
COORD dwWriteCoord, // 起始位置
LPDWORD lpNumberOfCharsWritten // 已写个数
);
FillConsoleOutputAttribute从屏幕缓冲区中指定的坐标位置开始,为指定数量的字符单元设置字符属性
BOOL FillConsoleOutputAttribute(
HANDLE hConsoleOutput,
WORD wAttribute,
//写到控制台屏幕缓冲区的属性
DWORD nLength,
//将被设置成指定颜色属性的字符单元数目
COORD dwWriteCoord,
LPDWORD lpNumberOfAttrsWritten
//指向变量的指针,变量用来存放被设置属性字符单元的实际数目。
);
控制台屏幕缓冲区
屏幕缓冲区是一个在控制台窗口输出的二维字符及颜色数组。一个控制台可以包含多个屏幕缓冲区,当前屏幕缓冲区指的是显示在屏幕上的那个缓冲区。
系统在创建新控制台时就会创建一个屏幕缓冲区。调用CreateFile函数指定CONOUT$值便可打开控制台的当前屏幕缓冲区。程序可以CreateConsoleScreenBuffer函数为它的控制台创建额外的屏幕缓冲区。一个新的屏幕缓冲区用自己的句柄调用SetConsoleActiveScreenBuffer函数便可设置为当前缓冲区。然而,不管是否是当前缓冲区,都可以被访问以进行读取及写入操作。
每个屏幕缓冲区都有自己的二维字符信息记录数组。每个字符信息都被存储在CHAR_INFO结构中,该结构中指定了Unicode或ANSI字符以及显示字符时的前景及背景颜色。
每个屏幕缓冲区的关联属性都可以被单独设置。这也意味着变更控制台的当前屏幕缓冲区的效果会很有意思。屏幕缓冲区的关联属性包括:
屏幕缓冲区大小,按字符行列记。
文本属性(WriteFile或WriteConsole函数用于“显示”文本所用的前景及背景)。
窗口大小及定位(在控制台窗口中显示的屏幕缓冲区的矩形区域)。
光标位置,外观及可见度。
输出模式(ENABLE_PROCESSED_OUTPUT及ENABLE_WRAP_AT_EOL_OUTPUT)。关于控制台输出模式的更多信息,请参见高级控制台模式。
技术
双缓冲技术(解决屏幕闪烁问题)
http://www.cnblogs.com/xdblog/p/4783364.html
1.新建一个屏幕缓冲区(此时不可见)
CreateConsoleScreenBuffer();
2.在新建的屏幕缓冲区中写入想要一次显示的内容
WriteConsole();
3.把该缓冲区设置为当前缓冲区(可见)
SetConsoleActiveScreenBuffer();
下面是一个是用控制台api编写的一个画图小程序
源码如下:
#include
#include
int main(void)
{
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
INPUT_RECORD mouseRec;
DWORD res;
COORD crPos, crHome = {0, 0};
CONSOLE_CURSOR_INFO cursorinfo= {1, 0};
SetConsoleCursorInfo(handle_out, &cursorinfo);
printf("[Cursor Position] X: %2lu Y: %2lu\n", 0, 0);
while(1)
{
ReadConsoleInput(handle_in, &mouseRec, 1, &res);
if(mouseRec.EventType == MOUSE_EVENT)
{
if(mouseRec.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
if(mouseRec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
{
break;
}
}
crPos = mouseRec.Event.MouseEvent.dwMousePosition;
GetConsoleScreenBufferInfo(handle_out, &bInfo);
SetConsoleCursorPosition(handle_out, crHome);
printf("[Cursor Position] X: %2lu Y: %2lu", crPos.X, crPos.Y);
SetConsoleCursorPosition(handle_out, bInfo.dwCursorPosition);
switch(mouseRec.Event.MouseEvent.dwButtonState)
{
case FROM_LEFT_1ST_BUTTON_PRESSED:
FillConsoleOutputCharacter(handle_out, 'A', 1, crPos, &res);
break;
case RIGHTMOST_BUTTON_PRESSED:
FillConsoleOutputCharacter(handle_out, 'a', 1, crPos, &res);
break;
default:
break;
}
}
}
CloseHandle(handle_out);
CloseHandle(handle_in);
return 0;
}
效果图:
哇第四篇文章了!!
很多人觉得他们在思考,而实际上他们只是在重新整理自己的偏见。——威廉· 詹姆斯
给我点十个赞我就买杯可乐庆祝下