📄 ask.cpp
字号:
// ask.cpp
#include <windows.h>
#include <stdio.h>
#include "msc.h"
#include "ask.h"
#include "oemio.h"
static int GetKey ( int nType ) ;
static int GetVirtualKey ( const INPUT_RECORD *pInputRecord ) ;
static void ConsoleClearLine ( void ) ;
// 僐儞僜乕儖偐傜僉乕傪庢摼偟丄OK 偐 CHANCEL傪曉偡乮ANSI斉乯
// 儊僢僙乕僕偼昗弨僄儔乕弌椡偵昞帵偡傞
// 昗弨擖椡偑儕僟僀儗僋僩偝傟偰偄偨傜 0 傪曉偡
// nType 偑 MB_OK 偺応崌丗 ^C 偼 1丄偦傟埲奜偼 0 傪曉偡
// nType 偑 MB_OKCANCEL 偺応崌丗 ^C 偍傛傃 ESC 偼 1丄偦傟埲奜偼 0 傪曉偡
// nType 偑 MB_YESNO 偺応崌丗 ^C丒ESC丒N 偼 1丄ENTER丒Y 偼 0 傪曉偡
// nType 偑 MB_YESNOCANCEL 偺応崌丗^C丒ESC 偼 -1丄N 偼 1丄ENTER丒Y 偼 0 傪曉偡
int AskA ( const char *szMessage, int nType ) {
// 儊僢僙乕僕傪弌椡偡傞応崌
if ( szMessage && *szMessage ) {
if ( fisatty ( stdout ) ) fflush ( stdout ) ;
fflush ( stderr ) ;
fputs ( szMessage, stderr ) ;
fflush ( stderr ) ;
int nResult = GetKey ( nType ) ;
ConsoleClearLine () ;
return nResult ;
}
// 儊僢僙乕僕傪弌椡偟側偄応崌
return GetKey ( nType ) ;
}
// 僐儞僜乕儖偐傜僉乕傪庢摼偟丄OK 偐 CHANCEL傪曉偡乮UNICODE斉乯
// 儊僢僙乕僕偼昗弨僄儔乕弌椡偵昞帵偡傞
// 昗弨擖椡偑儕僟僀儗僋僩偝傟偰偄偨傜 0 傪曉偡
// nType 偑 MB_OK 偺応崌丗 ^C 偼 1丄偦傟埲奜偼 0 傪曉偡
// nType 偑 MB_OKCANCEL 偺応崌丗^C 偍傛傃 ESC 偼 1丄偦傟埲奜偼 0 傪曉偡
// nType 偑 MB_YESNO 偺応崌丗 ^C丒ESC丒N 偼 1丄ENTER丒Y 偼 0 傪曉偡
int AskW ( const wchar_t *szMessage, int nType ) {
// 儊僢僙乕僕傪弌椡偡傞応崌
if ( szMessage && *szMessage ) {
if ( fisatty ( stdout ) ) fflush ( stdout ) ;
fflush ( stderr ) ;
fputws ( szMessage, stderr ) ;
fflush ( stderr ) ;
int nResult = GetKey ( nType ) ;
ConsoleClearLine () ;
return nResult ;
}
// 儊僢僙乕僕傪弌椡偟側偄応崌
return GetKey ( nType ) ;
}
// 僉乕傪庢摼偟丄0 偐 1 傪曉偡
// 昗弨擖椡偑儕僟僀儗僋僩偝傟偰偄偨傜 0 傪曉偡
static int GetKey ( int nType ) {
// 昗弨擖椡傪専嵏
HANDLE hConsole = fget_osfhandle ( stdin ) ;
unsigned long dwOldMode ;
if ( ! GetConsoleMode ( hConsole, & dwOldMode ) ) return 0 ; // error
FlushConsoleInputBuffer ( hConsole ) ;
SetConsoleMode ( hConsole, 0 ) ; // ^C 偺夝庍傪柍岠偵偡傞
int nResult = 0 ;
while ( 1 ) {
int cChar ;
INPUT_RECORD InputRecord ;
unsigned long nReadLength ;
if ( IsNT () ) {
if ( ! ReadConsoleInputW ( hConsole, & InputRecord, 1, & nReadLength ) || ! nReadLength ) break ; // error
if ( InputRecord.EventType != KEY_EVENT || ! InputRecord.Event.KeyEvent.bKeyDown ) continue ;
cChar = (wchar_t) InputRecord.Event.KeyEvent.uChar.UnicodeChar ;
}
else {
if ( ! ReadConsoleInputA ( hConsole, & InputRecord, 1, & nReadLength ) || ! nReadLength ) break ; // error
if ( InputRecord.EventType != KEY_EVENT || ! InputRecord.Event.KeyEvent.bKeyDown ) continue ;
cChar = (unsigned char) InputRecord.Event.KeyEvent.uChar.AsciiChar ;
}
if ( ! cChar ) cChar = - GetVirtualKey ( & InputRecord ) ;
if ( nType == MB_YESNOCANCEL ) {
if ( cChar == 'Y' || cChar == 'y' || cChar == 0x0D ) {
break ;
}
if ( cChar == 'N' || cChar == 'n' ) {
nResult = 1 ;
break ;
}
if ( cChar == 0x1B || cChar == 3 ) {
nResult = -1 ;
break ;
}
}
if ( nType == MB_YESNO ) {
if ( cChar == 'Y' || cChar == 'y' || cChar == 0x0D ) {
break ;
}
if ( cChar == 'N' || cChar == 'n' || cChar == 0x1B || cChar == 3 ) {
nResult = 1 ;
break ;
}
}
if ( nType == MB_OKCANCEL ) {
if ( cChar == 3 || cChar == 0x1B ) {
nResult = 1 ;
break ;
}
if ( cChar ) {
break ;
}
}
if ( nType == MB_OK ) {
if ( cChar == 3 ) {
nResult = 1 ;
break ;
}
if ( cChar ) {
break ;
}
}
}
FlushConsoleInputBuffer ( hConsole ) ;
SetConsoleMode ( hConsole, dwOldMode ) ;
return nResult ;
}
// 壓埵係寘偵壖憐僉乕僐乕僪丄忋埵係寘偵僔僼僩僉乕忬懺傪曉偡
static int GetVirtualKey ( const INPUT_RECORD *pInputRecord ) {
int nVirtualKey = pInputRecord->Event.KeyEvent.wVirtualKeyCode ;
switch ( nVirtualKey ) {
case VK_CAPITAL : // CAPS LOCK key
case VK_MENU : // ALT key
case VK_CONTROL : // CTRL key
case VK_SHIFT : // SHIFT key
case VK_NUMLOCK : // NUM LOCK key
case VK_SCROLL : // SCROLL LOCK key
return 0 ;
}
int nShiftKeyState = pInputRecord->Event.KeyEvent.dwControlKeyState ;
nShiftKeyState &= ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED ) ;
return nVirtualKey | ( nShiftKeyState << 16 ) ;
}
// 僐儞僜乕儖偺侾峴傪僋儕傾偡傞
static void ConsoleClearLine ( void ) {
HANDLE hConsole = fget_osfhandle ( stderr ) ;
if ( hConsole == INVALID_HANDLE_VALUE ) return ;
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo ;
if ( ! GetConsoleScreenBufferInfo ( hConsole, & ConsoleInfo ) ) return ;
fputc ( '\r', stderr ) ;
for ( int nCount = ConsoleInfo.dwSize.X - 1 ; nCount ; nCount -- ) fputc ( 0x20, stderr ) ;
fputc ( '\r', stderr ) ;
fflush ( stderr ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -