ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

choice.c
Go to the documentation of this file.
00001 /*
00002  *  CHOICE.C - internal command.
00003  *
00004  *
00005  *  History:
00006  *
00007  *    12 Aug 1999 (Eric Kohl)
00008  *        started.
00009  *
00010  *    01 Sep 1999 (Eric Kohl)
00011  *        Fixed help text.
00012  *
00013  *    26 Sep 1999 (Paolo Pantaleo)
00014  *        Fixed timeout.
00015  *
00016  *    02 Apr 2005 (Magnus Olsen
00017  *        Remove Hardcode string so
00018  *        they can be translate
00019  *
00020  */
00021 
00022 #include <precomp.h>
00023 
00024 #ifdef INCLUDE_CMD_CHOICE
00025 
00026 
00027 #define GC_TIMEOUT  -1
00028 #define GC_NOKEY    0   //an event occurred but it wasn't a key pressed
00029 #define GC_KEYREAD  1   //a key has been read
00030 
00031 
00032 static INT
00033 GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds)
00034 {
00035 //--------------------------------------------
00036 //  Get a character from standard input but with a timeout.
00037 //  The function will wait a limited amount
00038 //  of time, then the function returns GC_TIMEOUT.
00039 //
00040 //  dwMilliseconds is the timeout value, that can
00041 //  be set to INFINITE, so the function works like
00042 //  stdio.h's getchar()
00043 
00044     HANDLE hInput;
00045     DWORD  dwRead;
00046 
00047     INPUT_RECORD lpBuffer;
00048 
00049     hInput = GetStdHandle (STD_INPUT_HANDLE);
00050 
00051     //if the timeout experied return GC_TIMEOUT
00052     if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT)
00053         return GC_TIMEOUT;
00054 
00055     //otherwise get the event
00056     ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead);
00057 
00058     //if the event is a key pressed
00059     if ((lpBuffer.EventType == KEY_EVENT) &&
00060         (lpBuffer.Event.KeyEvent.bKeyDown == TRUE))
00061     {
00062         //read the key
00063 #ifdef _UNICODE
00064         *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar;
00065 #else
00066         *ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar;
00067 #endif
00068         return GC_KEYREAD;
00069     }
00070 
00071     //else return no key
00072     return GC_NOKEY;
00073 }
00074 
00075 static INT
00076 IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
00077 {
00078     LPTCH p = lpString;
00079     INT val = 0;
00080 
00081     while (*p)
00082     {
00083         if (bCaseSensitive)
00084         {
00085             if (*p == cKey)
00086                 return val;
00087         }
00088         else
00089         {
00090             if (_totlower (*p) == _totlower (cKey))
00091                 return val;
00092         }
00093 
00094         val++;
00095         p++;
00096     }
00097 
00098     return -1;
00099 }
00100 
00101 
00102 INT
00103 CommandChoice (LPTSTR param)
00104 {
00105     LPTSTR lpOptions;
00106     TCHAR Options[6];
00107     LPTSTR lpText    = NULL;
00108     BOOL   bNoPrompt = FALSE;
00109     BOOL   bCaseSensitive = FALSE;
00110     BOOL   bTimeout = FALSE;
00111     INT    nTimeout = 0;
00112     TCHAR  cDefault = _T('\0');
00113     INPUT_RECORD ir;
00114     LPTSTR p, np;
00115     LPTSTR *arg;
00116     INT    argc;
00117     INT    i;
00118     INT    val;
00119 
00120     INT GCret;
00121     TCHAR Ch;
00122     DWORD amount,clk;
00123 
00124     LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4);
00125     lpOptions = Options;
00126 
00127     if (_tcsncmp (param, _T("/?"), 2) == 0)
00128     {
00129         ConOutResPaging(TRUE,STRING_CHOICE_HELP);
00130         return 0;
00131     }
00132 
00133     /* retrieve text */
00134     p = param;
00135 
00136     while (TRUE)
00137     {
00138         if (*p == _T('\0'))
00139             break;
00140 
00141         if (*p != _T('/'))
00142         {
00143             lpText = p;
00144                 break;
00145         }
00146         np = _tcschr (p, _T(' '));
00147         if (!np)
00148             break;
00149         p = np + 1;
00150     }
00151 
00152     /* build parameter array */
00153     arg = split (param, &argc, FALSE, FALSE);
00154 
00155     /* evaluate arguments */
00156     if (argc > 0)
00157     {
00158         for (i = 0; i < argc; i++)
00159         {
00160             if (_tcsnicmp (arg[i], _T("/c"), 2) == 0)
00161             {
00162                 if (arg[i][2] == _T(':'))
00163                     lpOptions = &arg[i][3];
00164                 else
00165                     lpOptions = &arg[i][2];
00166 
00167                 if (_tcslen (lpOptions) == 0)
00168                 {
00169                     ConErrResPuts(STRING_CHOICE_ERROR);
00170                     freep (arg);
00171                     return 1;
00172                 }
00173             }
00174             else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0)
00175             {
00176                 bNoPrompt = TRUE;
00177             }
00178             else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0)
00179             {
00180                 bCaseSensitive = TRUE;
00181             }
00182             else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0)
00183             {
00184                 LPTSTR s;
00185 
00186                 if (arg[i][2] == _T(':'))
00187                 {
00188                     cDefault = arg[i][3];
00189                     s = &arg[i][4];
00190                 }
00191                 else
00192                 {
00193                     cDefault = arg[i][2];
00194                     s = &arg[i][3];
00195                 }
00196 
00197                 if (*s != _T(','))
00198                 {
00199                     ConErrResPuts(STRING_CHOICE_ERROR_TXT);
00200                     freep (arg);
00201                     return 1;
00202                 }
00203 
00204                 s++;
00205                 nTimeout = _ttoi(s);
00206                 bTimeout = TRUE;
00207             }
00208             else if (arg[i][0] == _T('/'))
00209             {
00210                 ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, arg[i]);
00211                 freep (arg);
00212                 return 1;
00213             }
00214         }
00215     }
00216 
00217     /* print text */
00218     if (lpText)
00219         ConOutPrintf (_T("%s"), lpText);
00220 
00221     /* print options */
00222     if (bNoPrompt == FALSE)
00223     {
00224         ConOutPrintf (_T("[%c"), lpOptions[0]);
00225 
00226         for (i = 1; (unsigned)i < _tcslen (lpOptions); i++)
00227             ConOutPrintf (_T(",%c"), lpOptions[i]);
00228 
00229         ConOutPrintf (_T("]?"));
00230     }
00231 
00232     ConInFlush ();
00233 
00234     if(!bTimeout)
00235     {
00236         while (TRUE)
00237         {
00238             ConInKey (&ir);
00239 
00240             val = IsKeyInString (lpOptions,
00241 #ifdef _UNICODE
00242                                  ir.Event.KeyEvent.uChar.UnicodeChar,
00243 #else
00244                                  ir.Event.KeyEvent.uChar.AsciiChar,
00245 #endif
00246                                  bCaseSensitive);
00247 
00248             if (val >= 0)
00249             {
00250                 ConOutPrintf (_T("%c\n"), lpOptions[val]);
00251 
00252                 nErrorLevel = val + 1;
00253 
00254                 break;
00255             }
00256 
00257             Beep (440, 50);
00258         }
00259 
00260         freep (arg);
00261         TRACE ("ErrorLevel: %d\n", nErrorLevel);
00262         return 0;
00263     }
00264 
00265     clk = GetTickCount ();
00266     amount = nTimeout*1000;
00267 
00268 loop:
00269     GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));
00270 
00271     switch (GCret)
00272     {
00273         case GC_TIMEOUT:
00274             TRACE ("GC_TIMEOUT\n");
00275             TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
00276             break;
00277 
00278         case GC_NOKEY:
00279             TRACE ("GC_NOKEY\n");
00280             TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
00281             goto loop;
00282 
00283         case GC_KEYREAD:
00284             TRACE ("GC_KEYREAD\n");
00285             TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
00286             TRACE ("read %c", Ch);
00287             if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
00288             {
00289                 Beep (440, 50);
00290                 goto loop;
00291             }
00292             cDefault=Ch;
00293             break;
00294     }
00295 
00296     TRACE ("exiting wait loop after %d msecs\n",
00297                 GetTickCount () - clk);
00298 
00299     val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
00300     ConOutPrintf (_T("%c\n"), lpOptions[val]);
00301 
00302     nErrorLevel = val + 1;
00303 
00304     freep (arg);
00305 
00306     TRACE ("ErrorLevel: %d\n", nErrorLevel);
00307 
00308     return 0;
00309 }
00310 #endif /* INCLUDE_CMD_CHOICE */
00311 
00312 /* EOF */

Generated on Fri May 25 2012 04:16:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.