控制台程序,用了许多函数

#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阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容