今天學習的控制臺API的整理還有各種結(jié)構(gòu)體和控制臺程序設(shè)計的相關(guān)信息,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.關(guān)閉句柄
結(jié)構(gòu)體及類型說明
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;
// 屏幕緩沖區(qū)的以字符為單位的寬度(X)和高度(Y)。
COORD dwCursorPosition;
// 光標在屏幕緩沖區(qū)的坐標屋剑。
WORD wAttributes;
//?繪制文本润匙、背景的顏色等屬性,在調(diào)用輸出函數(shù)輸出到控制臺的時候就會作用
SMALL_RECT?srWindow;
//?控制臺窗口左上角和右下角對應(yīng)屏幕緩沖區(qū)的位置唉匾。該參數(shù)可以指定要輸出的特定屏幕緩沖區(qū)的矩形區(qū)域孕讳。
COORD dwMaximumWindowSize;
//?控制臺窗口以字符為單位的最大寬度和高度。
}?CONSOLE_SCREEN_BUFFER_INFO?;
API
獲取句柄API
HANDLE?GetStdHandle(DWORD?nStdHandle);
返回標準的輸入肄鸽、輸出或錯誤的設(shè)備的句柄卫病,也就是獲得輸入、輸出?/錯誤的屏幕緩沖區(qū)的句柄典徘。其參數(shù)nStdHandle的值為下面幾種類型的一種:
STD_INPUT_HANDLE?標準輸入的句柄
STD_OUTPUT_HANDLE?標準輸出的句柄
STD_ERROR_HANDLE?標準錯誤的句柄
設(shè)置屬性API
BOOL?SetConsoleTextAttribute(
HANDLE?hConsoleOutput,
//?使用GetStdHandle取得的句柄
WORD?wAttributes
//?設(shè)置文本蟀苛、背景色
);
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設(shè)置光標的信息
BOOL?SetConsoleCursorInfo(
HANDLE?hConsoleOutput,
//?使用GetStdHandle取得的句柄
CONST?CONSOLE_CURSOR_INFO?*lpConsoleCursorInfo?
//?光標信息
);
SetConsoleCursorPosition設(shè)置光標位置
BOOL?SetConsoleCursorPosition(
??HANDLE?hConsoleOutput,
??COORD?dwCursorPosition
);
SetConsoleTitle設(shè)置控制臺的標題
BOOL?SetConsoleTitle(
??LPCTSTR?lpConsoleTitle
);
SetConsoleActiveScreenBuffer設(shè)置活動屏幕緩沖區(qū)
BOOL SetConsoleActiveScreenBuffer(?
????HANDLE?hConsoleOutput?
);
獲取屬性API
GetConsoleScreenBufferInfo取得控制臺屏幕緩沖信息
BOOL?GetConsoleScreenBufferInfo(
??HANDLE?hConsoleOutput,
??PCONSOLE_SCREEN_BUFFER_INFO?lpConsoleScreenBufferInfo
);
讀寫API
ReadConsoleInput來獲取輸入事件
BOOL?ReadConsoleInput(??
HANDLE?hConsoleInput,?//輸入句柄??
PINPUT_RECORD?lpBuffer,//輸入事件結(jié)構(gòu)體的指針??
DWORD?nLength,?//要讀取的記錄數(shù)??
LPDWORD?lpNumberOfEventsRead?//用來接受成功讀取記錄數(shù)的指針??
);??
FillConsoleOutputCharacter 填充指定數(shù)據(jù)的字符
BOOL FillConsoleOutputCharacter(
HANDLE hConsoleOutput, // 句柄
TCHAR cCharacter, // 字符
DWORD nLength, // 字符個數(shù)
COORD dwWriteCoord, // 起始位置
LPDWORD lpNumberOfCharsWritten // 已寫個數(shù)
);
FillConsoleOutputAttribute從屏幕緩沖區(qū)中指定的坐標位置開始,為指定數(shù)量的字符單元設(shè)置字符屬性
BOOL FillConsoleOutputAttribute(?
HANDLE?hConsoleOutput,?
WORD?wAttribute,?
//寫到控制臺屏幕緩沖區(qū)的屬性
DWORD?nLength,
//將被設(shè)置成指定顏色屬性的字符單元數(shù)目
COORD?dwWriteCoord,
LPDWORD?lpNumberOfAttrsWritten
//指向變量的指針逮诲,變量用來存放被設(shè)置屬性字符單元的實際數(shù)目帜平。
);
控制臺屏幕緩沖區(qū)
屏幕緩沖區(qū)是一個在控制臺窗口輸出的二維字符及顏色數(shù)組。一個控制臺可以包含多個屏幕緩沖區(qū)梅鹦,當前屏幕緩沖區(qū)指的是顯示在屏幕上的那個緩沖區(qū)裆甩。
系統(tǒng)在創(chuàng)建新控制臺時就會創(chuàng)建一個屏幕緩沖區(qū)。調(diào)用CreateFile函數(shù)指定CONOUT$值便可打開控制臺的當前屏幕緩沖區(qū)齐唆。程序可以CreateConsoleScreenBuffer函數(shù)為它的控制臺創(chuàng)建額外的屏幕緩沖區(qū)嗤栓。一個新的屏幕緩沖區(qū)用自己的句柄調(diào)用SetConsoleActiveScreenBuffer函數(shù)便可設(shè)置為當前緩沖區(qū)。然而,不管是否是當前緩沖區(qū)茉帅,都可以被訪問以進行讀取及寫入操作叨叙。
每個屏幕緩沖區(qū)都有自己的二維字符信息記錄數(shù)組。每個字符信息都被存儲在CHAR_INFO結(jié)構(gòu)中堪澎,該結(jié)構(gòu)中指定了Unicode或ANSI字符以及顯示字符時的前景及背景顏色擂错。
每個屏幕緩沖區(qū)的關(guān)聯(lián)屬性都可以被單獨設(shè)置。這也意味著變更控制臺的當前屏幕緩沖區(qū)的效果會很有意思樱蛤。屏幕緩沖區(qū)的關(guān)聯(lián)屬性包括:
屏幕緩沖區(qū)大小钮呀,按字符行列記。
文本屬性(WriteFile或WriteConsole函數(shù)用于“顯示”文本所用的前景及背景)昨凡。
窗口大小及定位(在控制臺窗口中顯示的屏幕緩沖區(qū)的矩形區(qū)域)爽醋。
光標位置,外觀及可見度土匀。
輸出模式(ENABLE_PROCESSED_OUTPUT及ENABLE_WRAP_AT_EOL_OUTPUT)子房。關(guān)于控制臺輸出模式的更多信息,請參見高級控制臺模式就轧。
技術(shù)
雙緩沖技術(shù)(解決屏幕閃爍問題)
http://www.cnblogs.com/xdblog/p/4783364.html
1.新建一個屏幕緩沖區(qū)(此時不可見)
CreateConsoleScreenBuffer();
2.在新建的屏幕緩沖區(qū)中寫入想要一次顯示的內(nèi)容
WriteConsole();
3.把該緩沖區(qū)設(shè)置為當前緩沖區(qū)(可見)
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;
}
效果圖:
哇第四篇文章了6视!
很多人覺得他們在思考镇饺,而實際上他們只是在重新整理自己的偏見乎莉。——威廉· 詹姆斯
給我點十個贊我就買杯可樂慶祝下