Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenchoice.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
1.7.6.1
|