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

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

unix.superglobalmegacorp.com

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