📄 choice.c
字号:
/* * 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. */#include "config.h"#ifdef INCLUDE_CMD_CHOICE#include "cmd.h"#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 readstatic INTGetCharacterTimeout (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 *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar; return GC_KEYREAD; } //else return no key return GC_NOKEY;}static INTIsKeyInString (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;}INTCommandChoice (LPTSTR cmd, LPTSTR param){ LPTSTR lpOptions = _T("YN"); 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; if (_tcsncmp (param, _T("/?"), 2) == 0) { ConOutPuts (_T("Waits for the user to choose one of a set of choices.\n") _T("\n") _T("CHOICE [/C[:]choices][/N][/S][/T[:]c,nn][text]\n") _T("\n") _T(" /C[:]choices Specifies allowable keys. Default is YN.\n") _T(" /N Do not display choices and ? at the end of the prompt string.\n") _T(" /S Treat choice keys as case sensitive.\n") _T(" /T[:]c,nn Default choice to c after nn seconds.\n") _T(" text Prompt string to display.\n") _T("\n") _T("ERRORLEVEL is set to offset of key user presses in choices.")); 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); /* 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) { ConErrPuts (_T("Invalid option. Expected format: /C[:]options")); 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(',')) { ConErrPuts (_T("Invalid option. Expected format: /T[:]c,nn")); freep (arg); return 1; } s++; nTimeout = _ttoi(s); bTimeout = TRUE; } else if (arg[i][0] == _T('/')) { ConErrPrintf (_T("Illegal Option: %s"), 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, ir.Event.KeyEvent.uChar.UnicodeChar, bCaseSensitive); if (val >= 0) { ConOutPrintf (_T("%c\n"), lpOptions[val]); nErrorLevel = val + 1; break; } MessageBeep (-1); } freep (arg); return 0; } clk = GetTickCount (); amount = nTimeout*1000;loop: GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk)); switch (GCret) { case GC_TIMEOUT:#ifdef _DEBUG DebugPrintf (_T("GC_TIMEOUT\n")); DebugPrintf (_T("elapsed %d msecs\n"), GetTickCount () - clk);#endif /* _DEBUG */ break; case GC_NOKEY:#ifdef _DEBUG DebugPrintf(_T("GC_NOKEY\n")); DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk);#endif /* _DEBUG */ goto loop; case GC_KEYREAD:#ifdef _DEBUG DebugPrintf(_T("GC_KEYREAD\n")); DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk); DebugPrintf(_T("read %c"), Ch);#endif /* _DEBUG */ if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1) { MessageBeep (-1); goto loop; } cDefault=Ch; break; }#ifdef _DEBUG DebugPrintf(_T("exiting wait loop after %d msecs\n"), GetTickCount () - clk);#endif /* _DEBUG */ val = IsKeyInString (lpOptions, cDefault, bCaseSensitive); ConOutPrintf (_T("%c\n"), lpOptions[val]); nErrorLevel = val + 1; freep (arg);#ifdef _DEBUG DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel);#endif /* _DEBUG */ return 0;}#endif /* INCLUDE_CMD_CHOICE *//* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -