mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 13:21:39 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
312
base/shell/cmd/choice.c
Normal file
312
base/shell/cmd/choice.c
Normal file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* CHOICE.C - internal command.
|
||||
*
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 12 Aug 1999 (Eric Kohl)
|
||||
* started.
|
||||
*
|
||||
* 01 Sep 1999 (Eric Kohl)
|
||||
* Fixed help text.
|
||||
*
|
||||
* 26 Sep 1999 (Paolo Pantaleo)
|
||||
* Fixed timeout.
|
||||
*
|
||||
* 02 Apr 2005 (Magnus Olsen
|
||||
* Remove Hardcode string so
|
||||
* they can be translate
|
||||
*
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
#ifdef INCLUDE_CMD_CHOICE
|
||||
|
||||
|
||||
#define GC_TIMEOUT -1
|
||||
#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed
|
||||
#define GC_KEYREAD 1 //a key has been read
|
||||
|
||||
|
||||
static INT
|
||||
GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds)
|
||||
{
|
||||
//--------------------------------------------
|
||||
// Get a character from standard input but with a timeout.
|
||||
// The function will wait a limited amount
|
||||
// of time, then the function returns GC_TIMEOUT.
|
||||
//
|
||||
// dwMilliseconds is the timeout value, that can
|
||||
// be set to INFINITE, so the function works like
|
||||
// stdio.h's getchar()
|
||||
|
||||
HANDLE hInput;
|
||||
DWORD dwRead;
|
||||
|
||||
INPUT_RECORD lpBuffer;
|
||||
|
||||
hInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
|
||||
//if the timeout experied return GC_TIMEOUT
|
||||
if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT)
|
||||
return GC_TIMEOUT;
|
||||
|
||||
//otherwise get the event
|
||||
ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead);
|
||||
|
||||
//if the event is a key pressed
|
||||
if ((lpBuffer.EventType == KEY_EVENT) &&
|
||||
(lpBuffer.Event.KeyEvent.bKeyDown == TRUE))
|
||||
{
|
||||
//read the key
|
||||
#ifdef _UNICODE
|
||||
*ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar;
|
||||
#else
|
||||
*ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar;
|
||||
#endif
|
||||
return GC_KEYREAD;
|
||||
}
|
||||
|
||||
//else return no key
|
||||
return GC_NOKEY;
|
||||
}
|
||||
|
||||
static INT
|
||||
IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
|
||||
{
|
||||
LPTCH p = lpString;
|
||||
INT val = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (bCaseSensitive)
|
||||
{
|
||||
if (*p == cKey)
|
||||
return val;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_totlower (*p) == _totlower (cKey))
|
||||
return val;
|
||||
}
|
||||
|
||||
val++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
CommandChoice (LPTSTR param)
|
||||
{
|
||||
LPTSTR lpOptions;
|
||||
TCHAR Options[6];
|
||||
LPTSTR lpText = NULL;
|
||||
BOOL bNoPrompt = FALSE;
|
||||
BOOL bCaseSensitive = FALSE;
|
||||
BOOL bTimeout = FALSE;
|
||||
INT nTimeout = 0;
|
||||
TCHAR cDefault = _T('\0');
|
||||
INPUT_RECORD ir;
|
||||
LPTSTR p, np;
|
||||
LPTSTR *arg;
|
||||
INT argc;
|
||||
INT i;
|
||||
INT val;
|
||||
|
||||
INT GCret;
|
||||
TCHAR Ch;
|
||||
DWORD amount,clk;
|
||||
|
||||
LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4);
|
||||
lpOptions = Options;
|
||||
|
||||
if (_tcsncmp (param, _T("/?"), 2) == 0)
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_CHOICE_HELP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* retrieve text */
|
||||
p = param;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (*p == _T('\0'))
|
||||
break;
|
||||
|
||||
if (*p != _T('/'))
|
||||
{
|
||||
lpText = p;
|
||||
break;
|
||||
}
|
||||
np = _tcschr (p, _T(' '));
|
||||
if (!np)
|
||||
break;
|
||||
p = np + 1;
|
||||
}
|
||||
|
||||
/* build parameter array */
|
||||
arg = split (param, &argc, FALSE);
|
||||
|
||||
/* evaluate arguments */
|
||||
if (argc > 0)
|
||||
{
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (_tcsnicmp (arg[i], _T("/c"), 2) == 0)
|
||||
{
|
||||
if (arg[i][2] == _T(':'))
|
||||
lpOptions = &arg[i][3];
|
||||
else
|
||||
lpOptions = &arg[i][2];
|
||||
|
||||
if (_tcslen (lpOptions) == 0)
|
||||
{
|
||||
ConErrResPuts(STRING_CHOICE_ERROR);
|
||||
freep (arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0)
|
||||
{
|
||||
bNoPrompt = TRUE;
|
||||
}
|
||||
else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0)
|
||||
{
|
||||
bCaseSensitive = TRUE;
|
||||
}
|
||||
else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0)
|
||||
{
|
||||
LPTSTR s;
|
||||
|
||||
if (arg[i][2] == _T(':'))
|
||||
{
|
||||
cDefault = arg[i][3];
|
||||
s = &arg[i][4];
|
||||
}
|
||||
else
|
||||
{
|
||||
cDefault = arg[i][2];
|
||||
s = &arg[i][3];
|
||||
}
|
||||
|
||||
if (*s != _T(','))
|
||||
{
|
||||
ConErrResPuts(STRING_CHOICE_ERROR_TXT);
|
||||
freep (arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
s++;
|
||||
nTimeout = _ttoi(s);
|
||||
bTimeout = TRUE;
|
||||
}
|
||||
else if (arg[i][0] == _T('/'))
|
||||
{
|
||||
ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, arg[i]);
|
||||
freep (arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print text */
|
||||
if (lpText)
|
||||
ConOutPrintf (_T("%s"), lpText);
|
||||
|
||||
/* print options */
|
||||
if (bNoPrompt == FALSE)
|
||||
{
|
||||
ConOutPrintf (_T("[%c"), lpOptions[0]);
|
||||
|
||||
for (i = 1; (unsigned)i < _tcslen (lpOptions); i++)
|
||||
ConOutPrintf (_T(",%c"), lpOptions[i]);
|
||||
|
||||
ConOutPrintf (_T("]?"));
|
||||
}
|
||||
|
||||
ConInFlush ();
|
||||
|
||||
if(!bTimeout)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
ConInKey (&ir);
|
||||
|
||||
val = IsKeyInString (lpOptions,
|
||||
#ifdef _UNICODE
|
||||
ir.Event.KeyEvent.uChar.UnicodeChar,
|
||||
#else
|
||||
ir.Event.KeyEvent.uChar.AsciiChar,
|
||||
#endif
|
||||
bCaseSensitive);
|
||||
|
||||
if (val >= 0)
|
||||
{
|
||||
ConOutPrintf (_T("%c\n"), lpOptions[val]);
|
||||
|
||||
nErrorLevel = val + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Beep (440, 50);
|
||||
}
|
||||
|
||||
freep (arg);
|
||||
TRACE ("ErrorLevel: %d\n", nErrorLevel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
clk = GetTickCount ();
|
||||
amount = nTimeout*1000;
|
||||
|
||||
loop:
|
||||
GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));
|
||||
|
||||
switch (GCret)
|
||||
{
|
||||
case GC_TIMEOUT:
|
||||
TRACE ("GC_TIMEOUT\n");
|
||||
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
||||
break;
|
||||
|
||||
case GC_NOKEY:
|
||||
TRACE ("GC_NOKEY\n");
|
||||
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
||||
goto loop;
|
||||
|
||||
case GC_KEYREAD:
|
||||
TRACE ("GC_KEYREAD\n");
|
||||
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
||||
TRACE ("read %c", Ch);
|
||||
if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
|
||||
{
|
||||
Beep (440, 50);
|
||||
goto loop;
|
||||
}
|
||||
cDefault=Ch;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE ("exiting wait loop after %d msecs\n",
|
||||
GetTickCount () - clk);
|
||||
|
||||
val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
|
||||
ConOutPrintf (_T("%c\n"), lpOptions[val]);
|
||||
|
||||
nErrorLevel = val + 1;
|
||||
|
||||
freep (arg);
|
||||
|
||||
TRACE ("ErrorLevel: %d\n", nErrorLevel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* INCLUDE_CMD_CHOICE */
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue