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

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

unix.superglobalmegacorp.com

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