Annotation of mstools/samples/console/console.c, revision 1.1.1.3

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.