控制臺程序,用了許多函數

#include

void ScrollScreenBuffer(HANDLE, INT);//???

VOID HandleInput(LPSTR szInput);

VOID ChangeConsoleTitle(LPSTR szNewTitle);

VOID GetConsoleInfo(HANDLE hOutput);

VOID ChangeTextColor(HANDLE hStdout, WORD wColor);

VOID ChangeBackgroundColor(HANDLE hConsole);

VOID ChangeUpCaseTextBackgroundColor(HANDLE hStdin, HANDLE hStdout);

void cls(HANDLE hConsole);

VOID UseBlockIO();

VOID ChangeMode(HANDLE hStdin, HANDLE hStdout);

void NewLine();

DWORD UseEvent();

VOID KeyEventProc(KEY_EVENT_RECORD);

VOID MouseEventProc(MOUSE_EVENT_RECORD);

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);

HANDLE hStdout;

HANDLE hStdin;

CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

int main(int argc, PCHAR argv[]){

LPSTR lpszPrompt = "type a line and press enter,255 max \n q to quit "

"\n i to show console info\n c to change background color \n s to change text color"

"\n t to find upper case character\n b to call useblackio\n u to change console titile"

"\n m to show console event \n r to change mode \n p to clear up console\n";

CHAR chBuffer[256];

DWORD cRead, cWritten, fdwMode, fdwOldMode;

WORD wOldColorAttrs;

//STDIN STDOUT 句柄

hStdin = GetStdHandle(STD_INPUT_HANDLE);

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE){

MessageBox(NULL, "獲取句柄出錯了", "控制臺提示", MB_OK);

return 1;

}

//當前字體顏色

if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo)){

MessageBox(NULL, "獲取字體顏色錯誤", "控制臺提示", MB_OK);

return 1;

}

wOldColorAttrs = csbiInfo.wAttributes;

//設置字符顏色(紅)和背景

ChangeTextColor(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY);

//輸出字符

if (!WriteConsole(

hStdout,//輸出句柄

lpszPrompt,//輸出字符串

lstrlen(lpszPrompt),//字符串長度

&cWritten,//返回實際輸出的長度

NULL//非 overlapped

)){

MessageBox(NULL, "輸出字符出錯", "控制臺提示", MB_OK);

return 1;

}

while (1){

//循環等待用戶輸入

ZeroMemory(chBuffer, 256);

if (!ReadConsole(

hStdin,//輸入控制臺句柄

chBuffer,//讀入數據的緩沖區

255,//緩沖區大小

&cRead,//實際讀到的大小

NULL//非 overlapped

)){

break;

}

HandleInput(chBuffer);

}

}

//處理用戶的輸入

VOID HandleInput(LPSTR szInput){

switch (szInput[0]){

case 'q'://退出進程

ExitProcess(0);

case 'i'://顯示控制臺信息

GetConsoleInfo(hStdout);

break;

case 'c'://設置界面背景顏色

ChangeBackgroundColor(hStdout);

break;

case 's'://設置設置文字顏色

ChangeTextColor(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY);

break;

case 't'://設置文字背景顏色

ChangeUpCaseTextBackgroundColor(hStdin, hStdout);

break;

case 'b'://使用 block IO

UseBlockIO();

break;

case 'u'://設置控制臺標題

ChangeConsoleTitle(&szInput[2]);

break;

case 'm'://使用事件

UseEvent();

break;

case 'r'://改變模式

ChangeMode(hStdin, hStdout);

break;

case 'p'://清屏

cls(hStdout);

break;

default://其他直接返回

return 1;

}

return 1;

}

//改變控制臺查看的標題

VOID ChangeConsoleTitle(LPSTR szNewTitle){

if (!SetConsoleTitle(szNewTitle)){

printf("設置控制臺窗口失敗\n");

}

}

//獲取控制臺信息

VOID GetConsoleInfo(HANDLE hOutput){

CONSOLE_FONT_INFO cfi;

DWORD dwProcessList[32];

DWORD dwAttachedProcess;

TCHAR szOutputBuffer[1024];

HWND hConsoleWindows;

DWORD dwWritten;

DWORD i;

CHAR szConsoleTitle[MAX_PATH];

//附屬的進程,不考慮多余32個的情況

dwAttachedProcess = GetConsoleProcessList(dwProcessList, 32);

if (dwAttachedProcess == 0){

printf("獲取附屬進程列表失敗\n");

}

//標題

if (!GetConsoleTitle(szConsoleTitle, MAX_PATH)){

printf("設置標題失敗\n");

}

//窗口句柄

hConsoleWindows = GetConsoleWindow();

//字體

GetCurrentConsoleFont(hOutput, FALSE, &cfi);

wsprintf(szOutputBuffer, "新附屬進程 %u 個: ", dwAttachedProcess);

for (i = 0; i< dwAttachedProcess; i++){

wsprintf(szOutputBuffer + lstrlen(szOutputBuffer), "%u, ", dwProcessList[i]);

}

//構造字符串

wsprintf(szOutputBuffer + lstrlen(szOutputBuffer),

"\n控制臺標題是 %s,\n窗口句柄是 0x%.8x\n 字體是 %u, 字體大小是X=%UY=%u",

szConsoleTitle, hConsoleWindows, cfi.nFont, cfi.dwFontSize.X, cfi.dwFontSize.Y);

//顯示獲取的信息

if (!WriteConsole(hOutput, szOutputBuffer, lstrlen(szOutputBuffer), &dwWritten, NULL)){

printf("獲取信息失敗\n");

}

}

//修改文字顏色 句柄 新的顏色

VOID ChangeTextColor(HANDLE hStdout, WORD wColor){

//設置文字屬性

if (!SetConsoleTextAttribute(hStdout, wColor)){

MessageBox(NULL, "設置文字屬性失敗", "控制臺提示", MB_OK);

return;

}

}

//修改背景顏色

VOID ChangeBackgroundColor(HANDLE hConsole){

COORD coord;

WORD wColor;

DWORD cWritten;

BOOL fSuccess;

coord.X = 0;//第一個cell

coord.Y = 0;//第一行

//背景和前景色

wColor = BACKGROUND_BLUE | BACKGROUND_RED | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;

//設置控制臺屬性

fSuccess = FillConsoleOutputAttribute(

hConsole,//handle句柄

wColor,//顏色

80 * 50,//填充cell數量

coord,//改變屬性的第一個cell

&cWritten//實際改變的情況

);

if (!fSuccess){

printf("設置控制臺屬性失敗\n");

}

}

//改變文字背景顏色

VOID ChangeUpCaseTextBackgroundColor(HANDLE hStdin, HANDLE hStdout){

DWORD dwLen, i, dwRead, dwWritten;

DWORD wColors[3];

BOOL fSuccess;

COORD coord;

HANDLE hSreenHandle;

CONSOLE_SCREEN_BUFFER_INFO csbi;

PCHAR lpCharacter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2048);

coord.X = 0;//起始cell

coord.Y = 0;

//讀取outputcharacher

if (!ReadConsoleOutputCharacter(hStdout, lpCharacter, 2047, coord, &dwRead)){

printf("讀取outputcharacher錯誤\n");

}

//獲取screenbufferinfo

GetConsoleScreenBufferInfo(hStdout, &csbi);

dwLen = lstrlen(lpCharacter);

//顏色數組

wColors[0] = BACKGROUND_RED;

wColors[1] = BACKGROUND_RED | BACKGROUND_GREEN;

wColors[2] = BACKGROUND_GREEN;

for (i = 0; i< dwLen; i++){

//差債大寫字母

if (lpCharacter[i]>= 'A' && lpCharacter[i] <= 'Z'){

//如果是大寫,將大寫字母開始位置的3個cell文字背景改為3中不同的顏色

coord.X = i / csbi.dwSize.X;

coord.Y = i%csbi.dwSize.Y;

fSuccess = WriteConsoleOutputAttribute(

hStdout,//句柄

wColors,

3,

coord,//起始位置

&dwWritten

);

if (!fSuccess){

printf("改變文字背景顏色失敗\n");

}

}

}

}

//清屏

void cls(HANDLE hConsole){

COORD coordScreen = { 0, 0 };//鼠標指針的位置

DWORD cCharsWritten;

CONSOLE_SCREEN_BUFFER_INFO csbi;

DWORD dwConSize;

//當前buffer中文字cell數目

if (!GetConsoleScreenBufferInfo(hConsole, &csbi)){

return;

}

dwConSize = csbi.dwSize.X*csbi.dwSize.Y;

//將整個屏幕填充

if (!FillConsoleOutputCharacter(hConsole, (TCHAR)' ', dwConSize, coordScreen, &cCharsWritten)){

return;

}

//獲取文字屬性

if (!GetConsoleScreenBufferInfo(hConsole, &csbi)){

return;

}

//設置buffer屬性

if (!FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten)){

return;

}

//將鼠標指針移到起始位置

SetConsoleCursorPosition(hConsole, coordScreen);

}

//使用BlockIO

VOID UseBlockIO(){

HANDLE hStdout, hNewScreenBuffer;

SMALL_RECT srctReadRect;

SMALL_RECT srctWriteRect;

CHAR_INFO chiBuffer[160];//[2][80]

COORD coordBufSize;

COORD coordBufCoord;

BOOL fSuccess;

//獲得句柄

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

//新建buffer

hNewScreenBuffer = CreateConsoleScreenBuffer(

GENERIC_READ | GENERIC_WRITE,//可讀可寫

0,//不共享

NULL,//默認安全屬性

CONSOLE_TEXTMODE_BUFFER,//must be TEXTMODE

NULL

);

if (hStdout == INVALID_HANDLE_VALUE || hNewScreenBuffer == INVALID_HANDLE_VALUE){

printf("創建新的緩存失敗 %d\n", GetLastError());

return;

}

//設置屏幕的buffer

if (!SetConsoleActiveScreenBuffer(hNewScreenBuffer)){

printf("設置屏幕的緩存失敗 %d\n", GetLastError());

return;

}

//設置源cell矩陣

srctReadRect.Top = 0;//top left row 0 col 0

srctReadRect.Left = 0;

srctReadRect.Bottom = 1;//bot right row 1 col 79

srctReadRect.Right = 79;

//臨時buffer大小為2行3列?

coordBufSize.Y = 2;

coordBufSize.X = 80;

//臨時buffer的起始位置

coordBufCoord.X = 0;

coordBufCoord.Y = 0;

//從屏幕buffer賦值內容到臨時buffer

fSuccess = ReadConsoleOutput(

hStdout,//源

chiBuffer,//目的

coordBufSize,//目的buffer大小

coordBufCoord,//目的起始位置

&srctReadRect//源的起始位置

);

if (!fSuccess){

printf("從屏幕buffer復制內容到臨時buffer失敗 %d\n", GetLastError());

return;

}

//設置目的cells矩陣

srctWriteRect.Top = 10;//top lt row 10 col 0

srctWriteRect.Left = 0;

srctWriteRect.Bottom = 11;//bot rt row 11 col 79

srctWriteRect.Right = 79;

//從臨時buffer向新的屏幕buffer復制

fSuccess = WriteConsoleOutput(hNewScreenBuffer, chiBuffer, coordBufSize, coordBufCoord, &srctWriteRect);

if (!fSuccess){

printf("從臨時buffer向新的屏幕buffer復制失敗 %d\n", GetLastError());

return;

}

//等一段時間愛你

Sleep(10000);

//恢復

if (!SetConsoleActiveScreenBuffer(hStdout)){

printf("恢復出錯%d\n", GetLastError());

return;

}

}

//改變控制臺的模式,關閉 ENABLE_LINE_INPUT ENABLE_ECHO_INPUT

VOID ChangeMode(HANDLE hStdin, HANDLE hStdout){

LPSTR lpszPrompt = "mode changeed type any key,or q to quit: ";

CHAR chBuffer[256];

DWORD fdwMode, fdwOldMode;

DWORD cRead, cWritten;

//獲取當前模式

if (!GetConsoleMode(hStdin, &fdwOldMode)){

MessageBox(NULL, "獲取遞簽模式失敗", "控制臺提示", MB_OK);

return;

}

//修改模式并重新設置

fdwMode = fdwOldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);

if (!SetConsoleMode(hStdin, fdwMode)){

MessageBox(NULL, "設置失敗", "控制臺提示", MB_OK);

return;

}

//換行

NewLine();

//循環等待輸入并處理

while (1){

if (!WriteFile(hStdout, lpszPrompt, lstrlen(lpszPrompt), &cWritten, NULL)){

printf("WriteFile\n");

return;

}

if (!ReadFile(hStdin, chBuffer, 1, &cRead, NULL)){

break;

}

if (chBuffer[0] == '\r'){

NewLine();

} else if (!WriteFile(hStdout, chBuffer, cRead, &cWritten, NULL)){

break;

} else{

NewLine();

}

if (chBuffer[0] == 'q'){

break;//輸入q,退出

}

}

//恢復模式

SetConsoleMode(hStdin, fdwOldMode);

}

//新行,滾動屏幕

void NewLine(){

if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo)){

MessageBox(NULL, "GetConsoleScreenBufferInfo", "控制臺提示", MB_OK);

return;

}

csbiInfo.dwCursorPosition.X = 0;

if ((csbiInfo.dwSize.Y - 1) == csbiInfo.dwCursorPosition.Y){

//ScrollScreenBuffer(hStdout, 1);

} else{

csbiInfo.dwCursorPosition.Y += 1;

}

if (!SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition)){

MessageBox(NULL, "SetConsoleCursorPosition", "控制臺提示", MB_OK);

return;

}

}

DWORD UseEvent(){

CHAR chBuffer[256];

DWORD cRead;

HANDLE hStdin;

DWORD cNumRead, fdwMode, fdwSaveOldMode, i;

INPUT_RECORD irInBuf[128];

//獲取標準輸入句柄

hStdin = GetStdHandle(STD_INPUT_HANDLE);

if (hStdin == INVALID_HANDLE_VALUE){

printf("GetStdHandle\n");

}

//保存當前的控制臺模式

if (!GetConsoleMode(hStdin, &fdwSaveOldMode)){

printf("GetConsoleMode\n");

}

//使窗口響應鼠標輸入事件

fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;

if (!SetConsoleMode(hStdin, fdwMode)){

printf("SetConsoleMode\n");

}

//循環讀取輸入

while (1){

//等待事件

if (!ReadConsoleInput(

hStdin,//輸入句柄

irInBuf,//保存輸入的緩沖區

128,//緩沖區大小

&cNumRead//實際讀取的大小

)){

printf("ReadConsoleInput\n");

}

//顯示事件

for (i = 0; i< cNumRead; i++){

switch (irInBuf[i].EventType){

case KEY_EVENT://鍵盤輸入

KeyEventProc(irInBuf[i].Event.KeyEvent);

break;

case MOUSE_EVENT://鼠標輸入

MouseEventProc(irInBuf[i].Event.MouseEvent);

break;

case WINDOW_BUFFER_SIZE_EVENT://RESIZE

ResizeEventProc(irInBuf[i].Event.WindowBufferSizeEvent);

break;

case FOCUS_EVENT://focus事件

case MENU_EVENT://menu事件

break;

default:

printf("unknown event type\n");

break;

}

}

}

return 0;

}

//鍵盤事件

VOID KeyEventProc(KEY_EVENT_RECORD ker){

CHAR szMsg[256];

wsprintf(szMsg, "KEY_EVENT_RECORD \n char = %c", ker.uChar);

MessageBox(NULL, szMsg, "EVENT", MB_OK);

}

//鼠標事件

VOID MouseEventProc(MOUSE_EVENT_RECORD mer){

CHAR szMsg[256];

wsprintf(szMsg, "MOUSE_EVENT_RECORD\n button state %d\nmouse positionX=%u,Y=%u", mer.dwButtonState, mer.dwMousePosition.X, mer.dwMousePosition.Y);

MessageBox(NULL, szMsg, "EVENT", MB_OK);

if (IDOK == MessageBox(NULL, "Exit?", "EVENT", MB_OKCANCEL)){

ExitProcess(0);

}

}

//重置大小事件

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr){

CHAR szMsg[256];

wsprintf(szMsg, "WINDOW_BUFFER_SIZE_RECORD\nX=%u,Y=%u", wbsr.dwSize.X, wbsr.dwSize.Y);

MessageBox(NULL, szMsg, "EVENT", MB_OK);

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容