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