Annotation of mstools/samples/console/console.c, revision 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.