- 最後登錄
- 2024-3-17
- 在線時間
- 235 小時
- 註冊時間
- 2008-5-3
- 閱讀權限
- 30
- 精華
- 4
- UID
- 4114704
- 帖子
- 1061
- 積分
- 1327 點
- 潛水值
- 4415 米
| 若對尊貴或贊助會員有任何疑問,歡迎向我們查詢。我們的即時通或MSN: admin@eyny.com 在 Visual Studio 9\VC\crt\src 裡有 getch.c
x86 定義下:
- _Check_return_ _CRT_NONSTDC_DEPRECATE(_getch) _CRTIMP int __cdecl getch(void);
- int __cdecl _getch (void)
- {
- int ch;
- _mlock(_CONIO_LOCK); /* secure the console lock */
- __TRY
- ch = _getch_nolock(); /* input the character */
- __FINALLY
- _munlock(_CONIO_LOCK); /* release the console lock */
- __END_TRY_FINALLY
- return ch;
- }
複製代碼
其中 _mlock 與 _munlock 進行臨界區鎖定與解除,實作為:
- void __cdecl _lock (int locknum)
- {
- if ( _locktable[locknum].lock == NULL ) { // Create/open the lock,if necessary
- if ( !_mtinitlocknum(locknum) )
- _amsg_exit( _RT_LOCK );
- }
- EnterCriticalSection( _locktable[locknum].lock ); //Enter the critical section
- }
- void __cdecl _unlock ( int locknum )
- {
- LeaveCriticalSection( _locktable[locknum].lock ); //leave the critical section
- }
複製代碼
再看 _getch_nolock :
- int __cdecl _getch_nolock (void)
- {
- INPUT_RECORD ConInpRec;
- DWORD NumRead;
- const CharPair *pCP;
- int ch = 0; /* single character buffer */
- DWORD oldstate;
- // check pushback buffer (chbuf) a for character
- if ( chbuf != EOF ) {
- // something there, clear buffer and return the character.
- ch = (unsigned char)(chbuf & 0xFF);
- chbuf = EOF;
- return ch;
- }
- // _coninpfh, the handle to the console input, is created the first
- // time that either _getch() or _cgets() or _kbhit() is called.
-
- if (_coninpfh == -2 ) __initconin();
- if (_coninpfh == -1) return EOF;
- // Switch to raw mode (no line input, no echo input)
-
- GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
- SetConsoleMode( (HANDLE)_coninpfh, 0L );
- for (;;) {
- // Get a console input event.
- if ( !ReadConsoleInput( (HANDLE)_coninpfh, &ConInpRec,
- 1L, &NumRead )
- || (NumRead == 0L) )
- {
- ch = EOF;
- break;
- }
- // Look for, and decipher, key events.
-
- if ( (ConInpRec.EventType == KEY_EVENT) &&
- ConInpRec.Event.KeyEvent.bKeyDown ) {
- if ( ch = (unsigned char)ConInpRec.Event.KeyEvent.uChar.AsciiChar )
- break;
- // either an extended code or an event which should
- // not be recognized. let _getextendedkeycode() do the work...
-
- if ( pCP = _getextendedkeycode( &(ConInpRec.Event.KeyEvent) ) ) {
- ch = pCP->LeadChar;
- chbuf = pCP->SecondChar;
- break;
- }
- }
- }
- SetConsoleMode( (HANDLE)_coninpfh, oldstate ); //Restore previous console mode
- return ch;
- }
複製代碼
亦即,先將 console handle 保存於 _coninpfh,
再透過 ReadConsoleInput 取得 ASCII Code 與 Extended Code (if need)。
所以....
在 VC9 CRT 的實作裡,getch 只是 API 的一份包裝。... |
|