|
|
1.1 ! root 1: #include <windows.h> ! 2: #include <stdio.h> ! 3: #include <string.h> ! 4: #include <stdlib.h> ! 5: #include "console.h" ! 6: ! 7: /* used to set our initial console screen buffer size */ ! 8: #define CONX 80 ! 9: #define CONY 43 ! 10: ! 11: /* prototypes of externally defined demo functions */ ! 12: extern void demoAllocFree(HANDLE hConOld, HANDLE *hConsole); ! 13: extern void demoCreate(HANDLE hConOld); ! 14: extern void demoFillAtt(HANDLE hConOut); ! 15: extern void demoFillChar(HANDLE hConOut); ! 16: extern void demoFlush(HANDLE hConOut); ! 17: extern void demoCursor(HANDLE hConOut); ! 18: extern void demoConMode(HANDLE hConOut); ! 19: extern void demoConInfo(HANDLE hConOut); ! 20: extern void demoGetTitle(HANDLE hConOut); ! 21: extern void demoGetLargest(HANDLE hConOut); ! 22: extern void demoGetNumEvents(HANDLE hConOut); ! 23: extern void demoGetNumBut(HANDLE hConOut); ! 24: extern void demoReadConOut(HANDLE hConOut); ! 25: extern void demoReadConChar(HANDLE hConOut); ! 26: extern void demoScrollCon(HANDLE hConOut); ! 27: extern void demoSizeInfo(HANDLE hConOut); ! 28: extern void demoSetCtrlHandler(HANDLE hConOut); ! 29: extern void demoWriteIn(HANDLE hConOut); ! 30: ! 31: /* information to display on the screen for user to click on */ ! 32: PCHAR conAPIs[] = { ! 33: "AllocConsole Creates a console for the current process", ! 34: "CreateConsoleScreenBuffer Returns a handle to a new screen buffer", ! 35: "FillConsoleOutputAttribute Writes attributes to the screen buffer", ! 36: "FillConsoleOutputCharacter Writes characters to the screen buffer", ! 37: "FlushConsoleInputBuffer Clears the console input buffer", ! 38: "FreeConsole Frees the current console", ! 39: "GetConsoleCursorInfo Returns console size and visibility", ! 40: "GetConsoleMode Returns console input or output mode", ! 41: "GetConsoleScreenBufferInfo Returns screen-buffer information", ! 42: "GetConsoleTitle Returns console-window title", ! 43: "GetLargestConsoleWindowSize Returns largest possible window size", ! 44: "GetNumberOfConsoleInputEvents Retrieves number of console-queue events", ! 45: "GetNumberOfConsoleMouseButtons Retrieves number of mouse buttons", ! 46: "PeekConsoleInput Previews console input data", ! 47: "ReadConsoleInput Reads console input data", ! 48: "ReadConsoleOutput Reads screen-buffer data", ! 49: "ReadConsoleOutputAttribute Reads a console attribute string", ! 50: "ReadConsoleOutputCharacter Reads a screen-buffer string", ! 51: "ScrollConsoleScreenBuffer Scrolls data in the screen buffer", ! 52: "SetConsoleActiveScreenBuffer Changes displayed screen buffer", ! 53: "SetConsoleCursorInfo Sets cursor size and visibility", ! 54: "SetConsoleCursorPosition Sets cursor position", ! 55: "SetConsoleMode Sets console input or output mode", ! 56: "SetConsoleScreenBufferSize Changes screen-buffer size", ! 57: "SetConsoleTextAttribute Sets attributes for screen text", ! 58: "SetConsoleTitle Sets console-window title string", ! 59: "SetConsoleWindowInfo Sets console window size", ! 60: "SetConsoleCtrlHandler Sets console ctrl-c handler", ! 61: "WriteConsoleInput Writes to console input buffer", ! 62: "WriteConsoleOutput Writes to screen buffer", ! 63: "WriteConsoleOutputAttribute Writes an attribute string to console", ! 64: "WriteConsoleOutputCharacter Writes a character string to console" ! 65: }; ! 66: ! 67: /* this variable holds the number next to the API on the screen that */ ! 68: /* the user clicks on */ ! 69: enum cAPIs { ALLOC = 1, CREATE, FILLATT, FILLCHAR, FLUSH, FREE, GETCUR, ! 70: GETMODE, GETCONINFO, GETTITLE, GETLARGEST, GETNUMEV, GETNUMBUT, PEEK, ! 71: READCONIN, READCONOUT, READCONATT, READCONCHAR, SCROLL, SETACTIVE, ! 72: SETCURINF, SETCURPOS, SETMODE, SETSIZE, SETATT, SETTITLE, SETINFO, ! 73: SETHAND, WRITEIN, WRITEOUT, WRITEATT, WRITECHAR }; ! 74: ! 75: ! 76: /***************************************************************** ! 77: * FUNCTION: myGetchar(void) * ! 78: * * ! 79: * PURPOSE: get a single character from the standard input handle * ! 80: * * ! 81: * INPUT: none * ! 82: * * ! 83: * RETURNS: the char received from the console * ! 84: *****************************************************************/ ! 85: ! 86: CHAR myGetchar(void) ! 87: { ! 88: HANDLE hStdIn; /* standard input */ ! 89: DWORD dwInputMode; /* to save the input mode */ ! 90: BOOL bSuccess; ! 91: CHAR chBuf; /* buffer to read into */ ! 92: DWORD dwRead; ! 93: ! 94: /* get the standard input handle to read from. There is only one */ ! 95: /* instance of standard input per process at any given time */ ! 96: hStdIn = GetStdHandle(STD_INPUT_HANDLE); ! 97: PERR((int) hStdIn != -1, "GetStdHandle"); ! 98: /* save the console mode */ ! 99: bSuccess = GetConsoleMode(hStdIn, &dwInputMode); ! 100: PERR(bSuccess, "GetconsoleMode"); ! 101: /* disable line input. Echo input must be disabled when disabling */ ! 102: /* line input */ ! 103: bSuccess = SetConsoleMode(hStdIn, dwInputMode & ~ENABLE_LINE_INPUT & ! 104: ~ENABLE_ECHO_INPUT); ! 105: PERR(bSuccess, "SetConsoleMode"); ! 106: /* read a character from the console input */ ! 107: bSuccess = ReadFile(hStdIn, &chBuf, sizeof(chBuf), &dwRead, NULL); ! 108: PERR(bSuccess, "ReadFile"); ! 109: /* restore the original console input mode */ ! 110: bSuccess = SetConsoleMode(hStdIn, dwInputMode); ! 111: PERR(bSuccess, "SetConsoleMode"); ! 112: return(chBuf); ! 113: } ! 114: ! 115: ! 116: /******************************************************************** ! 117: * FUNCTION: perrError(void) * ! 118: * * ! 119: * PURPOSE: beep twice and abort program * ! 120: * * ! 121: * INPUT: none * ! 122: * * ! 123: * RETURNS: none * ! 124: * * ! 125: * COMMENTS: only called from perr() when a fatal error has occurred * ! 126: ********************************************************************/ ! 127: ! 128: void perrError(void) ! 129: { ! 130: DWORD dwLastError; /* for debugger purposes */ ! 131: ! 132: dwLastError = GetLastError(); ! 133: /* we can't output an error message - beep instead */ ! 134: Beep(600, 500); ! 135: Beep(700, 500); ! 136: exit(1); ! 137: } ! 138: ! 139: ! 140: /********************************************************************* ! 141: * FUNCTION: perr(PCHAR szFileName, int line, PCHAR szApiName, * ! 142: * DWORD dwError) * ! 143: * * ! 144: * PURPOSE: report API errors. Allocate a new console buffer, display * ! 145: * error number and error text, restore previous console * ! 146: * buffer * ! 147: * * ! 148: * INPUT: current source file name, current line number, name of the * ! 149: * API that failed, and the error number * ! 150: * * ! 151: * RETURNS: none * ! 152: *********************************************************************/ ! 153: ! 154: /* this is the size of the buffer for the error message text */ ! 155: #define MSG_BUF_SIZE 512 ! 156: ! 157: void perr(PCHAR szFileName, int line, PCHAR szApiName, DWORD dwError) ! 158: { ! 159: BOOL bSuccess; ! 160: HANDLE hConTemp; /* temp console buffer to put error message on */ ! 161: HANDLE hCurrentCon; /* to save the current console so we can restore it */ ! 162: CHAR szTemp[256]; ! 163: DWORD cCharsWritten; ! 164: DWORD dwLastError; /* for debugging purposes */ ! 165: CHAR msgBuf[MSG_BUF_SIZE]; /* buffer for message text from system */ ! 166: ! 167: /* create a handle to the current console buffer */ ! 168: hCurrentCon = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ | ! 169: FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ! 170: if ((int) hCurrentCon == -1) ! 171: { ! 172: dwLastError = GetLastError(); ! 173: /* just in case this works */ ! 174: printf("Fatal error in perr() on line %d: %d\n", __LINE__, dwLastError); ! 175: Beep(600, 500); ! 176: exit(1); ! 177: } ! 178: /* create a temporary console buffer that we can write on */ ! 179: hConTemp = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, ! 180: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, ! 181: NULL); ! 182: if ((int) hConTemp == -1) ! 183: { ! 184: dwLastError = GetLastError(); ! 185: printf("Fatal error in perr() on line %d: %d\n", __LINE__, dwLastError); ! 186: Beep(600, 500); ! 187: exit(1); ! 188: } ! 189: /* make the temp buffer to the current buffer */ ! 190: bSuccess = SetConsoleActiveScreenBuffer(hConTemp); ! 191: if (!bSuccess) ! 192: { ! 193: dwLastError = GetLastError(); ! 194: printf("Fatal error in perr() on line %d: %d\n", __LINE__, dwLastError); ! 195: Beep(600, 500); ! 196: exit(1); ! 197: } ! 198: /* set red on white text for future text output */ ! 199: SetConsoleTextAttribute(hConTemp, FOREGROUND_RED | BACKGROUND_WHITE); ! 200: /* format our error message */ ! 201: sprintf(szTemp, "%s: Error %d from %s on line %d\n", szFileName, ! 202: dwError, szApiName, line); ! 203: /* write the message to the console */ ! 204: bSuccess = WriteFile(hConTemp, szTemp, strlen(szTemp), &cCharsWritten, ! 205: NULL); ! 206: if (!bSuccess) ! 207: perrError(); ! 208: memset(msgBuf, 0, sizeof(msgBuf)); ! 209: /* get the text description for that error number from the system */ ! 210: cCharsWritten = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | ! 211: getConX(hConTemp), NULL, dwError, MAKELANGID(0, SUBLANG_ENGLISH_US), ! 212: msgBuf, sizeof(msgBuf), NULL); ! 213: if (!cCharsWritten) ! 214: perrError(); ! 215: else ! 216: { ! 217: /* write the text description to the console */ ! 218: bSuccess = WriteFile(hConTemp, msgBuf, strlen(msgBuf), &cCharsWritten, ! 219: NULL); ! 220: if (!bSuccess) ! 221: perrError(); ! 222: } ! 223: myGetchar(); ! 224: /* reset the current buffer to the original one */ ! 225: bSuccess = SetConsoleActiveScreenBuffer(hCurrentCon); ! 226: if (!bSuccess) ! 227: perrError(); ! 228: CloseHandle(hConTemp); ! 229: bSuccess = CloseHandle(hCurrentCon); ! 230: if (!bSuccess) ! 231: perrError(); ! 232: return; ! 233: } ! 234: ! 235: /************************************************************************* ! 236: * FUNCTION: myPuts(HANDLE hConsole, PCHAR s) * ! 237: * * ! 238: * PURPOSE: write a string to the given console buffer, appending a cr/lf * ! 239: * * ! 240: * INPUT: the console to write to, and the string to write * ! 241: * * ! 242: * RETURNS: TRUE if success, FALSE if an error occured * ! 243: *************************************************************************/ ! 244: ! 245: BOOL myPuts(HANDLE hConsole, PCHAR s) ! 246: { ! 247: BOOL bSuccess; ! 248: DWORD cCharsWritten; ! 249: const PCHAR crlf = "\n"; ! 250: BOOL retflag = TRUE; ! 251: ! 252: /* write the string to the console */ ! 253: bSuccess = WriteFile(hConsole, s, strlen(s), &cCharsWritten, NULL); ! 254: PERR(bSuccess, "WriteFile"); ! 255: retflag = bSuccess; ! 256: /* put a carriage return & line feed after the string */ ! 257: bSuccess = WriteFile(hConsole, crlf, strlen(crlf), &cCharsWritten, NULL); ! 258: PERR(bSuccess, "WriteFile"); ! 259: if (!bSuccess) ! 260: retflag = FALSE; ! 261: return(retflag); ! 262: } ! 263: ! 264: ! 265: /******************************************************************** ! 266: * FUNCTION: getConX(HANDLE hCon) * ! 267: * * ! 268: * PURPROSE: to get the current width of the console output buffer * ! 269: * * ! 270: * INPUT: the handle to get the information for * ! 271: * * ! 272: * RETURNS: the width of the current console output buffer, in chars * ! 273: ********************************************************************/ ! 274: ! 275: SHORT getConX(HANDLE hCon) ! 276: { ! 277: CONSOLE_SCREEN_BUFFER_INFO csbi; ! 278: BOOL bSuccess; ! 279: ! 280: bSuccess = GetConsoleScreenBufferInfo(hCon, &csbi); ! 281: PERR(bSuccess, "GetConsoleScreenBufferInfo"); ! 282: return(csbi.dwSize.X); ! 283: } ! 284: ! 285: ! 286: /********************************************************************* ! 287: * FUNCTION: getConY(HANDLE hCon) * ! 288: * * ! 289: * PURPROSE: to get the current height of the console output buffer * ! 290: * * ! 291: * INPUT: the handle to get the information for * ! 292: * * ! 293: * RETURNS: the height of the current console output buffer, in chars * ! 294: *********************************************************************/ ! 295: ! 296: ! 297: SHORT getConY(HANDLE hCon) ! 298: { ! 299: CONSOLE_SCREEN_BUFFER_INFO csbi; ! 300: BOOL bSuccess; ! 301: ! 302: bSuccess = GetConsoleScreenBufferInfo(hCon, &csbi); ! 303: PERR(bSuccess, "GetConsoleScreenBufferInfo"); ! 304: return(csbi.dwSize.Y); ! 305: } ! 306: ! 307: ! 308: /************************************************************************* ! 309: * FUNCTION: showConAPIs(HANDLE hConsole) * ! 310: * * ! 311: * PURPOSE: to display a list of console APIs on the given console buffer * ! 312: * * ! 313: * INPUT: the console to display the APIs on * ! 314: * * ! 315: * RETURNS: none * ! 316: *************************************************************************/ ! 317: ! 318: void showConAPIs(HANDLE hConsole) ! 319: { ! 320: COORD coordScreen = {CONX, CONY}; /* used to set the console buffer size */ ! 321: /* used to set the console window size */ ! 322: SMALL_RECT srWindowRect = {0, 0, CONX - 1, CONY - 1}; ! 323: int i; ! 324: BOOL bSuccess; ! 325: DWORD cCharsWritten; ! 326: CHAR szTemps[128]; ! 327: WORD wConBufSize; /* used to hold current console buffer size */ ! 328: ! 329: /* get the current console buffer size, in chars */ ! 330: wConBufSize = getConX(hConsole) * getConY(hConsole); ! 331: /* force an CONX x CONY screen */ ! 332: /* if the current buffer is larger than what we want, resize the */ ! 333: /* console window first, then the buffer */ ! 334: if (wConBufSize > CONX * CONY) ! 335: { ! 336: bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); ! 337: PERR(bSuccess, "SetConsoleWindowInfo"); ! 338: bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); ! 339: PERR(bSuccess, "SetConsoleScreenBufferSize"); ! 340: } ! 341: /* if the current buffer is smaller than what we want, resize the */ ! 342: /* buffer first, then the console window */ ! 343: if (wConBufSize < CONX * CONY) ! 344: { ! 345: bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); ! 346: PERR(bSuccess, "SetConsoleScreenBufferSize"); ! 347: bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); ! 348: PERR(bSuccess, "SetConsoleWindowInfo"); ! 349: } ! 350: coordScreen.X = 0; ! 351: coordScreen.Y = 0; ! 352: /* set the screen */ ! 353: bSuccess = FillConsoleOutputAttribute(hConsole, BACKGROUND_BLUE, ! 354: CONX * CONY, coordScreen, &cCharsWritten); ! 355: PERR(bSuccess, "FillConsoleOutputAttribute"); ! 356: /* set attributes for new writes to the console */ ! 357: bSuccess = SetConsoleTextAttribute(hConsole, BACKGROUND_BLUE | ! 358: FOREGROUND_WHITE); ! 359: PERR(bSuccess, "SetConsoleTextAttribute"); ! 360: /* fill screen with API list */ ! 361: for (i = 0; i < sizeof(conAPIs) / sizeof(conAPIs[0]); i++) ! 362: { ! 363: coordScreen.X = 0; ! 364: coordScreen.Y = (SHORT) (i + 2); /* start on third line (zero based) */ ! 365: /* position the cursor to start the API list */ ! 366: bSuccess = SetConsoleCursorPosition(hConsole, coordScreen); ! 367: PERR(bSuccess, "SetConsoleCursorPosition"); ! 368: /* format a line and write it to the screen */ ! 369: sprintf(szTemps, "%-3d%s", i + 1, conAPIs[i]); ! 370: myPuts(hConsole, szTemps); ! 371: /* color the number yellow on blue */ ! 372: bSuccess = FillConsoleOutputAttribute(hConsole, FOREGROUND_YELLOW | ! 373: FOREGROUND_INTENSITY | BACKGROUND_BLUE, 3, coordScreen, ! 374: &cCharsWritten); ! 375: PERR(bSuccess, "FillConsoleOutputAttribute"); ! 376: coordScreen.X = 3; ! 377: /* color text light cyan on blue */ ! 378: bSuccess = FillConsoleOutputAttribute(hConsole, FOREGROUND_CYAN | ! 379: FOREGROUND_INTENSITY | BACKGROUND_BLUE, strlen(conAPIs[i]), ! 380: coordScreen, &cCharsWritten); ! 381: PERR(bSuccess, "FillConsoleOutputAttribute"); ! 382: } ! 383: myPuts(hConsole, "\nClick on an API to see a demonstration of that API.\n" ! 384: "Hit ESC to exit the program.\n"); ! 385: return; ! 386: } ! 387: ! 388: ! 389: /************************************************************************* ! 390: * FUNCTION: putStatusLine(HANDLE hOut, PCHAR buf) * ! 391: * * ! 392: * PURPOSE: display a string on the top line of the console output buffer * ! 393: * * ! 394: * INPUT: the output handle, the string to display * ! 395: * * ! 396: * RETURNS: none * ! 397: *************************************************************************/ ! 398: ! 399: void putStatusLine(HANDLE hOut, PCHAR buf) ! 400: { ! 401: BOOL bSuccess; ! 402: /* position the status line at (0, 0) */ ! 403: const COORD dwWriteCoord = {0, 0}; ! 404: DWORD cCharsWritten; ! 405: int len; /* the length of the input string parameter */ ! 406: CHAR szTemp[256]; ! 407: SHORT sWidth; /* console width */ ! 408: ! 409: sWidth = getConX(hOut); ! 410: strcpy(szTemp, buf); ! 411: len = strlen(szTemp); ! 412: memset(szTemp + len, ' ', sWidth - len); /* blank out rest of line */ ! 413: /* write the string to the console at the correct position */ ! 414: bSuccess = WriteConsoleOutputCharacter(hOut, szTemp, sWidth, ! 415: dwWriteCoord, &cCharsWritten); ! 416: PERR(bSuccess, "WriteConsoleOutput"); ! 417: /* color the status line so it stands out */ ! 418: bSuccess = FillConsoleOutputAttribute(hOut, FOREGROUND_RED | ! 419: BACKGROUND_WHITE, sWidth, dwWriteCoord, &cCharsWritten); ! 420: PERR(bSuccess, "FillConsoleOutputAttribute"); ! 421: return; ! 422: } ! 423: ! 424: ! 425: /******************************************************************** ! 426: * FUNCTION: demoAPI(HANDLE *hConsole, enum cAPIs apiNumber) * ! 427: * * ! 428: * PURPOSE: call the correct demo function based on the input index * ! 429: * * ! 430: * INPUT: current console output buffer, and screen index of the API * ! 431: * to demonstrate * ! 432: * * ! 433: * RETURNS: none * ! 434: ********************************************************************/ ! 435: ! 436: static void demoAPI(HANDLE *phConsole, enum cAPIs apiNumber) ! 437: { ! 438: const COORD coordScreen = {0, 0}; ! 439: DWORD cCharsWritten; ! 440: BOOL bSuccess; ! 441: HANDLE hConTemp; ! 442: CHAR szConsoleTitle[128]; /* to store the console title */ ! 443: DWORD dwCharsRead; ! 444: ! 445: /* create a temp screen buffer to write to */ ! 446: hConTemp = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, ! 447: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, ! 448: NULL); ! 449: PERR((int) hConTemp != -1, "CreateConsoleScreenBuffer"); ! 450: /* make it the active buffer */ ! 451: bSuccess = SetConsoleActiveScreenBuffer(hConTemp); ! 452: PERR(bSuccess, "SetConsoleActiveScreenBuffer"); ! 453: /* clear screen & save the console title */ ! 454: cls(hConTemp); ! 455: bSuccess = FillConsoleOutputAttribute(hConTemp, BACKGROUND_CYAN, ! 456: getConX(hConTemp) * getConY(hConTemp), coordScreen, &cCharsWritten); ! 457: PERR(bSuccess, "FillConsoleOutputAttribute"); ! 458: bSuccess = SetConsoleTextAttribute(hConTemp, BACKGROUND_CYAN); ! 459: PERR(bSuccess, "SetConsoleTextAttribute"); ! 460: dwCharsRead = GetConsoleTitle(szConsoleTitle, sizeof(szConsoleTitle)); ! 461: PERR(dwCharsRead, "GetConsoleTitle"); ! 462: ! 463: /* flush the input buffer and call the correct demo function */ ! 464: bSuccess = FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); ! 465: PERR(bSuccess, "FlushConsoleInputBuffer"); ! 466: switch(apiNumber) ! 467: { ! 468: case ALLOC: ! 469: case FREE: ! 470: demoAllocFree(hConTemp, phConsole); ! 471: return; ! 472: break; ! 473: case CREATE: ! 474: case SETACTIVE: ! 475: case SETATT: ! 476: demoCreate(hConTemp); ! 477: break; ! 478: case FILLATT: ! 479: case WRITECHAR: ! 480: demoFillAtt(hConTemp); ! 481: break; ! 482: case FILLCHAR: ! 483: demoFillChar(hConTemp); ! 484: break; ! 485: case FLUSH: ! 486: demoFlush(hConTemp); ! 487: break; ! 488: case GETCUR: ! 489: case SETCURINF: ! 490: case SETCURPOS: ! 491: demoCursor(hConTemp); ! 492: break; ! 493: case GETMODE: ! 494: case SETMODE: ! 495: demoConMode(hConTemp); ! 496: break; ! 497: case GETCONINFO: ! 498: demoConInfo(hConTemp); ! 499: break; ! 500: case GETTITLE: ! 501: case SETTITLE: ! 502: demoGetTitle(hConTemp); ! 503: break; ! 504: case GETLARGEST: ! 505: demoGetLargest(hConTemp); ! 506: break; ! 507: case GETNUMEV: ! 508: case PEEK: ! 509: case READCONIN: ! 510: demoGetNumEvents(hConTemp); ! 511: break; ! 512: case GETNUMBUT: ! 513: demoGetNumBut(hConTemp); ! 514: break; ! 515: case READCONOUT: ! 516: case WRITEOUT: ! 517: case READCONATT: ! 518: case WRITEATT: ! 519: demoReadConOut(hConTemp); ! 520: break; ! 521: case READCONCHAR: ! 522: demoReadConChar(hConTemp); ! 523: break; ! 524: case SCROLL: ! 525: demoScrollCon(hConTemp); ! 526: break; ! 527: case SETSIZE: ! 528: case SETINFO: ! 529: demoSizeInfo(hConTemp); ! 530: break; ! 531: case SETHAND: ! 532: demoSetCtrlHandler(hConTemp); ! 533: break; ! 534: case WRITEIN: ! 535: demoWriteIn(hConTemp); ! 536: break; ! 537: default: ! 538: break; ! 539: } ! 540: CloseHandle(hConTemp); /* free temporary console buffer */ ! 541: /* reset active buffer to original buffer. If the temp buffer has been */ ! 542: /* resized, the console window will automatically be sized correctly */ ! 543: /* when the current console is set back to the old one */ ! 544: bSuccess = SetConsoleActiveScreenBuffer(*phConsole); ! 545: PERR(bSuccess, "SetConsoleActiveScreenBuffer"); ! 546: /* restore the original console title */ ! 547: bSuccess = SetConsoleTitle(szConsoleTitle); ! 548: PERR(bSuccess, "SetConsoleTitle"); ! 549: /* flush the input buffer to remove any 'leftover' clicks or key events */ ! 550: bSuccess = FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); ! 551: PERR(bSuccess, "FlushConsoleInputBuffer"); ! 552: return; ! 553: } ! 554: ! 555: ! 556: /************************************************************************ ! 557: * FUNCTION: cls(HANDLE hConsole) * ! 558: * * ! 559: * PURPOSE: clear the screen by filling it with blanks, then home cursor * ! 560: * * ! 561: * INPUT: the console buffer to clear * ! 562: * * ! 563: * RETURNS: none * ! 564: *************************************************************************/ ! 565: ! 566: void cls(HANDLE hConsole) ! 567: { ! 568: COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */ ! 569: BOOL bSuccess; ! 570: DWORD cCharsWritten; ! 571: ! 572: /* fill the entire screen with blanks */ ! 573: bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', ! 574: getConX(hConsole) * getConY(hConsole), coordScreen, &cCharsWritten); ! 575: PERR(bSuccess, "FillConsoleOutputCharacter"); ! 576: /* put the cursor at (0, 0) */ ! 577: bSuccess = SetConsoleCursorPosition(hConsole, coordScreen); ! 578: PERR(bSuccess, "SetConsoleCursorPosition"); ! 579: return; ! 580: } ! 581: ! 582: ! 583: /********************************************************************* ! 584: * FUNCTION: setConTitle * ! 585: * * ! 586: * PURPOSE: simply set the current console title. Called by each demo * ! 587: * function to specify the name of the source file that * ! 588: * contains the demo function. * ! 589: * * ! 590: * INPUT: null terminated string * ! 591: *********************************************************************/ ! 592: ! 593: void setConTitle(PCHAR szTitle) ! 594: { ! 595: BOOL bSuccess; ! 596: ! 597: /* set the console title to the input string parameter */ ! 598: bSuccess = SetConsoleTitle(szTitle); ! 599: PERR(bSuccess, "SetConsoleTitle"); ! 600: return; ! 601: } ! 602: ! 603: ! 604: /********************************************************************* ! 605: * FUNCTION: main * ! 606: * * ! 607: * PURPOSE: main input loop. Set up console input and output * ! 608: * attributes, then read the input queue and process input * ! 609: * events. If ESC is hit, end the process. If the mouse is * ! 610: * clicked, read the line from the output console where the * ! 611: * mouse was clicked. If an index number can be found at the * ! 612: * beginning of the line, call the appropriate demo function * ! 613: * to demonstrate that API. All input event information is * ! 614: * displayed on the status line on the top line. * ! 615: * * ! 616: * INPUT: none * ! 617: * * ! 618: * RETURNS: 1 if can't free console, 2 if can't allocate a console, 0 * ! 619: * for a normal exit * ! 620: *********************************************************************/ ! 621: ! 622: int main() ! 623: { ! 624: BOOL bSuccess; ! 625: HANDLE hStdIn, hStdOut; /* standard input and standard output */ ! 626: DWORD dwMode; ! 627: /* array of console input event records */ ! 628: INPUT_RECORD inputBuffer; ! 629: DWORD dwInputEvents; /* number of events actually read */ ! 630: CHAR bOutBuf[256]; /* buffer to format event information into */ ! 631: /* used to get the new console screen buffer size if it is changed */ ! 632: COORD coordScreen; /* used when reading the index number from the screen */ ! 633: CHAR *szLineBuf; /* buffer to read the index number into */ ! 634: DWORD cCharsRead; ! 635: enum cAPIs apiNumber; /* the index number of the API read from the screen */ ! 636: /* used when turning off the cursor */ ! 637: CONSOLE_CURSOR_INFO cci = {100, FALSE}; ! 638: ! 639: /* free the console and immediately allocate a new one. This is done so */ ! 640: /* that when debugging under ntsd, the application output will not be */ ! 641: /* intermingled with the debugger output. This section can be removed */ ! 642: /* without any change in the behavior of this program */ ! 643: bSuccess = FreeConsole(); ! 644: /* C run-time output will not work from now on! */ ! 645: if (!bSuccess) ! 646: { ! 647: Beep(600, 500); /* can't output an error message! */ ! 648: return(1); ! 649: } ! 650: bSuccess = AllocConsole(); ! 651: if (!bSuccess) ! 652: { ! 653: Beep(600, 500); /* can't output an error message! */ ! 654: return(2); ! 655: } ! 656: /* let's put up a meaningful console title */ ! 657: bSuccess = SetConsoleTitle("Win32 Console API Demo"); ! 658: PERR(bSuccess, "SetConsoleTitle"); ! 659: /* get the standard handles */ ! 660: hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); ! 661: PERR((int) hStdOut != -1, "GetStdHandle"); ! 662: hStdIn = GetStdHandle(STD_INPUT_HANDLE); ! 663: PERR((int) hStdIn != -1,"GetStdHandle"); ! 664: /* set up mouse and window input */ ! 665: bSuccess = GetConsoleMode(hStdIn, &dwMode); ! 666: PERR(bSuccess, "GetConsoleMode"); ! 667: /* when turning off ENABLE_LINE_INPUT, you MUST also turn off */ ! 668: /* ENABLE_ECHO_INPUT. */ ! 669: bSuccess = SetConsoleMode(hStdIn, (dwMode & ~(ENABLE_LINE_INPUT | ! 670: ENABLE_ECHO_INPUT)) | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); ! 671: PERR(bSuccess, "SetConsoleMode"); ! 672: /* hide the cursor */ ! 673: bSuccess = SetConsoleCursorInfo(hStdOut, &cci); ! 674: PERR(bSuccess, "SetConsoleCursorInfo"); ! 675: /* resize console to CONX * CONY and put list of console APIs up */ ! 676: showConAPIs(hStdOut); ! 677: /* This is the main input loop. Read from the input queue and process */ ! 678: /* the events read */ ! 679: szLineBuf = (char *) malloc(getConX(hStdOut)); ! 680: PERR(szLineBuf, "malloc"); ! 681: ! 682: for(;;) ! 683: { ! 684: /* read an input events from the input event queue */ ! 685: bSuccess = ReadConsoleInput(hStdIn, &inputBuffer, 1, &dwInputEvents); ! 686: PERR(bSuccess, "ReadConsoleInput"); ! 687: switch (inputBuffer.EventType) ! 688: { ! 689: case KEY_EVENT: ! 690: if (inputBuffer.Event.KeyEvent.bKeyDown) ! 691: { ! 692: /* display the key event info on the status line */ ! 693: sprintf(bOutBuf, "key: virtual=%d ascii=%c", ! 694: inputBuffer.Event.KeyEvent.wVirtualKeyCode, ! 695: inputBuffer.Event.KeyEvent.uChar.AsciiChar); ! 696: if (inputBuffer.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) ! 697: { ! 698: free(szLineBuf); /* free allocated line buffer */ ! 699: return(0); ! 700: } ! 701: putStatusLine(hStdOut, bOutBuf); ! 702: } ! 703: break; ! 704: case MOUSE_EVENT: ! 705: sprintf(bOutBuf, "mouse: %s at %d, %d", ! 706: (inputBuffer.Event.MouseEvent.dwEventFlags == MOUSE_MOVED ? ! 707: "moved" : "clicked"), inputBuffer.Event.MouseEvent.dwMousePosition.X, ! 708: inputBuffer.Event.MouseEvent.dwMousePosition.Y); ! 709: putStatusLine(hStdOut, bOutBuf); ! 710: /* was this a mouse click? If so dwEventFlags contains 0 */ ! 711: /* are any mouse buttons down? If so dwButtonState is not 0 */ ! 712: if (inputBuffer.Event.MouseEvent.dwEventFlags == 0 && ! 713: inputBuffer.Event.MouseEvent.dwButtonState) ! 714: { ! 715: coordScreen.X = 0; ! 716: coordScreen.Y = inputBuffer.Event.MouseEvent.dwMousePosition.Y; ! 717: /* read the line where the mouse clicked */ ! 718: bSuccess = ReadConsoleOutputCharacter(hStdOut, szLineBuf, ! 719: sizeof(szLineBuf), coordScreen, &cCharsRead); ! 720: PERR(bSuccess, "ReadConsoleOutputCharacter"); ! 721: /* scan for an index number at the beginning of that line. */ ! 722: /* if there was one read, call the correct demo function */ ! 723: if (sscanf(szLineBuf, "%d", &apiNumber)) ! 724: demoAPI(&hStdOut, apiNumber); ! 725: } ! 726: break; ! 727: case WINDOW_BUFFER_SIZE_EVENT: ! 728: sprintf(bOutBuf, "window: %d, %d", ! 729: inputBuffer.Event.WindowBufferSizeEvent.dwSize.X, ! 730: inputBuffer.Event.WindowBufferSizeEvent.dwSize.Y); ! 731: putStatusLine(hStdOut, bOutBuf); ! 732: Sleep(1000); ! 733: break; ! 734: } /* switch */ ! 735: } /* while */ ! 736: free(szLineBuf); /* free allocated line buffer */ ! 737: return(0); ! 738: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.