2 * CHOICE.C - internal command.
7 * 12 Aug 1999 (Eric Kohl)
10 * 01 Sep 1999 (Eric Kohl)
13 * 26 Sep 1999 (Paolo Pantaleo)
19 #ifdef INCLUDE_CMD_CHOICE
32 #define GC_NOKEY 0 //an event occurred but it wasn't a key pressed
33 #define GC_KEYREAD 1 //a key has been read
37 GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds)
39 //--------------------------------------------
40 // Get a character from standard input but with a timeout.
41 // The function will wait a limited amount
42 // of time, then the function returns GC_TIMEOUT.
44 // dwMilliseconds is the timeout value, that can
45 // be set to INFINITE, so the function works like
46 // stdio.h's getchar()
51 INPUT_RECORD lpBuffer;
53 hInput = GetStdHandle (STD_INPUT_HANDLE);
55 //if the timeout experied return GC_TIMEOUT
56 if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT)
59 //otherwise get the event
60 ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead);
62 //if the event is a key pressed
63 if ((lpBuffer.EventType == KEY_EVENT) &&
64 (lpBuffer.Event.KeyEvent.bKeyDown == TRUE))
68 *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar;
70 *ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar;
80 IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
94 if (_totlower (*p) == _totlower (cKey))
107 CommandChoice (LPTSTR cmd, LPTSTR param)
109 LPTSTR lpOptions = "YN";
110 LPTSTR lpText = NULL;
111 BOOL bNoPrompt = FALSE;
112 BOOL bCaseSensitive = FALSE;
113 BOOL bTimeout = FALSE;
115 TCHAR cDefault = _T('\0');
127 if (_tcsncmp (param, _T("/?"), 2) == 0)
129 ConOutPuts (_T("Waits for the user to choose one of a set of choices.\n"
131 "CHOICE [/C[:]choices][/N][/S][/T[:]c,nn][text]\n"
133 " /C[:]choices Specifies allowable keys. Default is YN.\n"
134 " /N Do not display choices and ? at the end of the prompt string.\n"
135 " /S Treat choice keys as case sensitive.\n"
136 " /T[:]c,nn Default choice to c after nn seconds.\n"
137 " text Prompt string to display.\n"
139 "ERRORLEVEL is set to offset of key user presses in choices."));
156 np = _tcschr (p, _T(' '));
162 /* build parameter array */
163 arg = split (param, &argc, FALSE);
165 /* evaluate arguments */
168 for (i = 0; i < argc; i++)
170 if (_tcsnicmp (arg[i], _T("/c"), 2) == 0)
172 if (arg[i][2] == _T(':'))
173 lpOptions = &arg[i][3];
175 lpOptions = &arg[i][2];
177 if (_tcslen (lpOptions) == 0)
179 ConErrPuts (_T("Invalid option. Expected format: /C[:]options"));
184 else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0)
188 else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0)
190 bCaseSensitive = TRUE;
192 else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0)
196 if (arg[i][2] == _T(':'))
198 cDefault = arg[i][3];
203 cDefault = arg[i][2];
209 ConErrPuts (_T("Invalid option. Expected format: /T[:]c,nn"));
218 else if (arg[i][0] == _T('/'))
220 ConErrPrintf (_T("Illegal Option: %s"), arg[i]);
229 ConOutPrintf (_T("%s"), lpText);
232 if (bNoPrompt == FALSE)
234 ConOutPrintf (_T("[%c"), lpOptions[0]);
236 for (i = 1; (unsigned)i < _tcslen (lpOptions); i++)
237 ConOutPrintf (_T(",%c"), lpOptions[i]);
239 ConOutPrintf (_T("]?"));
250 val = IsKeyInString (lpOptions,
252 ir.Event.KeyEvent.uChar.UnicodeChar,
254 ir.Event.KeyEvent.uChar.AsciiChar,
255 #endif /* _UNICODE */
260 ConOutPrintf (_T("%c\n"), lpOptions[val]);
262 nErrorLevel = val + 1;
274 clk = GetTickCount ();
275 amount = nTimeout*1000;
278 GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));
284 DebugPrintf (_T("GC_TIMEOUT\n"));
285 DebugPrintf (_T("elapsed %d msecs\n"), GetTickCount () - clk);
291 DebugPrintf(_T("GC_NOKEY\n"));
292 DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk);
298 DebugPrintf(_T("GC_KEYREAD\n"));
299 DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk);
300 DebugPrintf(_T("read %c"), Ch);
302 if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
312 DebugPrintf(_T("exiting wait loop after %d msecs\n"),
313 GetTickCount () - clk);
316 val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
317 ConOutPrintf (_T("%c\n"), lpOptions[val]);
319 nErrorLevel = val + 1;
324 DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel);
329 #endif /* INCLUDE_CMD_CHOICE */