C语言控制台操作API整理

今天学习的控制台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 <stdio.h>

#include <windows.h>

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;

}

效果图:

丘比特之箭~像不像!!

哇第四篇文章了!!


很多人觉得他们在思考,而实际上他们只是在重新整理自己的偏见。——威廉· 詹姆斯


给我点十个赞我就买杯可乐庆祝下


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容