📄 console.cpp
字号:
// Size of changing part
dwCompletionStringSize = dwCurrentCharOffset-dwCompletionOffset;
// Save intial changing part of completion in m_pchBuffer2
if (dwCompletionStringSize)
_tcsncpy(m_pchBuffer2,m_pchBuffer+dwCompletionOffset,dwCompletionStringSize);
m_pchBuffer2[dwCompletionStringSize] = 0;
// Calculate cursor position of point between changing and not changing ports
CompletionPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset);
CompletionPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset);
} // if first time tab
const TCHAR *pchCompletion = NULL;
// Direction
BOOL blnForward = !(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED);
if (m_pfReplaceCompletionCallback) // If we are using replace completion callback
pchCompletion = m_pfReplaceCompletionCallback(nCompletionIndex,
blnCompletionMode?&blnForward:NULL, // If this is first time we call the completion callback, do not change completion index
m_pchBuffer1,m_pchBuffer2);
if (pchCompletion) // If completion found
{
// Set cursor position to compeltion position
m_CursorPosition = CompletionPosition;
if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition))
return FALSE;
// Calculate buffer free space
ASSERT(m_dwBufferSize > dwCompletionOffset);
DWORD dwFree = m_dwBufferSize - dwCompletionOffset - 1;
// Save old completion string size
DWORD dwOldCompletionStringSize = dwCompletionStringSize;
// Write completion string to buffer
dwCompletionStringSize = _tcslen(pchCompletion);
// If there is not enough space in buffer, so we truncate the completion
if (dwCompletionStringSize > dwFree)
dwCompletionStringSize = dwFree;
if (dwCompletionStringSize)
{
// Copy competion into main buffer
_tcsncpy(m_pchBuffer+dwCompletionOffset,pchCompletion,dwCompletionStringSize);
// Write completion string to console
if (!Write(m_pchBuffer+dwCompletionOffset,dwCompletionStringSize))
return FALSE;
// Set new offsets
dwCurrentCharOffset = dwLastCharOffset = dwCompletionOffset + dwCompletionStringSize;
ASSERT(dwLastCharOffset < m_dwBufferSize);
}
// Erase rest from previous completion string, if the new completion is shorter than old
if (dwOldCompletionStringSize > dwCompletionStringSize)
{
_tcsnset(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,_T(' '),
dwOldCompletionStringSize - dwCompletionStringSize);
// Save cursor position
COORD pos = m_CursorPosition;
if (!Write(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,
dwOldCompletionStringSize - dwCompletionStringSize))
return FALSE;
// Set cursor position
m_CursorPosition = pos;
if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition))
return FALSE;
}
} // If completion found
// Ok, we are in completion mode
blnCompletionMode = TRUE;
}
else if (_istprint(ch))
{
if (blnCompletionMode) blnCompletionMode = FALSE;
if (dwLastCharOffset >= m_dwBufferSize-1)
{
ASSERT(dwLastCharOffset == m_dwBufferSize-1);
// Beep(1000,100);
continue;
}
TCHAR ch1;
//if (m_blnInsetMode)
ch1 = m_pchBuffer[dwCurrentCharOffset];
m_pchBuffer[dwCurrentCharOffset] = ch;
if ((m_blnInsetMode)||(dwCurrentCharOffset == dwLastCharOffset)) dwLastCharOffset++;
dwCurrentCharOffset++;
if (!Write(&ch,1)) return FALSE;
if (m_blnInsetMode)
{
COORD Cursor = m_CursorPosition;
DWORD ofs = dwCurrentCharOffset;
while(ofs <= dwLastCharOffset)
{
ch = m_pchBuffer[ofs];
m_pchBuffer[ofs] = ch1;
ch1 = ch;
ofs++;
}
if (dwCurrentCharOffset < dwLastCharOffset)
{
if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE;
if (m_LinesScrolled)
{
if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE;
Cursor.Y = SHORT(Cursor.Y - m_LinesScrolled);
}
// Update cursor position
m_CursorPosition = Cursor;
if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
}
}
}
ASSERT(InputRecord.Event.KeyEvent.wRepeatCount);
if (!InputRecord.Event.KeyEvent.wRepeatCount) return FALSE;
if (--InputRecord.Event.KeyEvent.wRepeatCount) goto KeyRepeat;
}
m_blnMoreMode = blnOldMoreMode;
return TRUE;
}
BOOL CConsole::GetTextAttribute(WORD& rwAttributes)
{
rwAttributes = m_wAttributes;
return TRUE;
}
// Parameters:
// dwBufferSize - size in chars of the input line buffer
//
// Rerturns:
// NULL - Failed.
// pointer to the input buffer
TCHAR * CConsole::Init(DWORD dwBufferSize, DWORD dwMaxHistoryLines)
{
if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn));
if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut));
m_hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (m_hStdIn == INVALID_HANDLE_VALUE)
{
// _ftprintf(stderr,_T("GetStdHandle(STD_INPUT_HANDLE) failed. GetLastError return 0x%X\n"),(unsigned)GetLastError());
goto Abort;
}
m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (m_hStdOut == INVALID_HANDLE_VALUE)
{
// _ftprintf(stderr,_T("GetStdHandle(STD_OUTPUT_HANDLE) failed. GetLastError return 0x%X\n"),(unsigned)GetLastError());
goto Abort;
}
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(m_hStdOut,&info))
{
// _ftprintf(stderr,_T("GetConsoleScreenBufferInfo(m_hStdOut,&info) failed. GetLastError return 0x%X\n"),(unsigned)GetLastError());
if (GetLastError() == 6) // redirected output
_ftprintf(stderr,_T("Redirection is not supported.\n"));
goto Abort;
}
m_wAttributes = info.wAttributes;
if (!m_blnOldInputModeSaved)
{
if (!GetConsoleMode(m_hStdIn,&m_dwOldInputMode))
{
if (GetLastError() == 6) // redirected input
_ftprintf(stderr,_T("Redirection is not supported.\n"));
// _ftprintf(stderr,_T("GetConsoleMode(0x%X,&m_dwOldINputMode) failed. GetLastError() returns 0x%X\n"),(int)m_hStdIn,GetLastError());
goto Abort;
}
m_blnOldInputModeSaved = TRUE;
}
// _ftprintf(stderr,_T("Calling GetConsoleMode(0x%X,&m_dwOldOutputMode) ...\n"),(int)m_hStdOut);
if (!m_blnOldOutputModeSaved)
{
if (!GetConsoleMode(m_hStdOut,&m_dwOldOutputMode))
goto Abort;
// _ftprintf(stderr,_T("Calling GetConsoleMode(0x%X,&m_dwOldOutputMode) done.\n"),(int)m_hStdOut);
m_blnOldOutputModeSaved = TRUE;
}
// _ftprintf(stderr,_T("Calling SetConsoleMode(0x%X,0) ...\n"),(int)m_hStdIn);
if (!SetConsoleMode(m_hStdIn,0))
goto Abort;
if (!SetConsoleMode(m_hStdOut,0))
goto Abort;
m_CursorPosition = info.dwCursorPosition;
m_BufferSize = info.dwSize;
CONSOLE_CURSOR_INFO cci;
cci.bVisible = TRUE;
cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
if (!SetConsoleCursorInfo(m_hStdOut,&cci)) goto Abort;
m_dwBufferSize = dwBufferSize;
if (m_pchBuffer) delete m_pchBuffer;
m_pchBuffer = NULL;
if (m_pchBuffer1) delete m_pchBuffer1;
m_pchBuffer1 = NULL;
if (m_pchBuffer2) delete m_pchBuffer2;
m_pchBuffer2 = NULL;
m_pchBuffer = new TCHAR [dwBufferSize];
if (!m_pchBuffer) goto Abort;
m_pchBuffer[dwBufferSize-1] = 0;
m_pchBuffer1 = new TCHAR [dwBufferSize];
if (!m_pchBuffer1) goto Abort;
m_pchBuffer1[dwBufferSize-1] = 0;
m_pchBuffer2 = new TCHAR [dwBufferSize];
if (!m_pchBuffer2) goto Abort;
m_pchBuffer2[dwBufferSize-1] = 0;
if (dwMaxHistoryLines)
{
if (!m_History.Init(dwBufferSize,dwMaxHistoryLines)) goto Abort;
}
return m_pchBuffer;
Abort:
if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn));
m_hStdIn = INVALID_HANDLE_VALUE;
if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut));
m_hStdOut = INVALID_HANDLE_VALUE;
if (m_pchBuffer) delete m_pchBuffer;
m_pchBuffer = NULL;
if (m_pchBuffer1) delete m_pchBuffer1;
m_pchBuffer1 = NULL;
if (m_pchBuffer2) delete m_pchBuffer2;
m_pchBuffer2 = NULL;
m_dwBufferSize = 0;
return NULL;
}
BOOL CConsole::WriteChar(TCHAR ch)
{
CHAR_INFO ci;
ci.Attributes = m_wAttributes;
#ifdef UNICODE
ci.Char.UnicodeChar = ch;
#else
ci.Char.AsciiChar = ch;
#endif
static COORD BufferSize = {1,1};
static COORD BufferCoord = {0,0};
SMALL_RECT Dest;
Dest.Bottom = Dest.Top = m_CursorPosition.Y;
Dest.Left = Dest.Right = m_CursorPosition.X;
return WriteConsoleOutput(m_hStdOut,&ci,BufferSize,BufferCoord,&Dest);
}
void CConsole::BeginScrollingOperation()
{
m_Lines = 0;
}
BOOL CConsole::WriteString(TCHAR *pchString, COORD Position)
{
CHAR_INFO ciBuffer[256];
int nSize = _tcslen(pchString);
if ((nSize > 256)||(nSize <= 0))
{
ASSERT(FALSE);
return FALSE;
}
COORD BufferSize;
BufferSize.X = (SHORT)nSize;
BufferSize.Y = 1;
static COORD BufferCoord = {0,0};
SMALL_RECT Dest;
Dest.Bottom = Dest.Top = Position.Y;
Dest.Right = SHORT((Dest.Left = Position.X) + nSize - 1);
while(nSize--)
{
ciBuffer[nSize].Attributes = m_wAttributes;
#ifdef UNICODE
ciBuffer[nSize].Char.UnicodeChar = pchString[nSize];
#else
ciBuffer[nSize].Char.AsciiChar = pchString[nSize];
#endif
}
return WriteConsoleOutput(m_hStdOut,ciBuffer,BufferSize,BufferCoord,&Dest);
}
BOOL CConsole::SetInsertMode(BOOL blnInsetMode)
{
if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE;
CONSOLE_CURSOR_INFO cci;
cci.bVisible = TRUE;
cci.dwSize = blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
BOOL ret = SetConsoleCursorInfo(m_hStdOut,&cci);
if (ret) m_blnInsetMode = blnInsetMode;
return ret;
}
void CConsole::SetReplaceCompletionCallback(ReplaceCompletionCallback pfCallback)
{
m_pfReplaceCompletionCallback = pfCallback;
}
void CConsole::DisableWrite()
{
m_blnDisableWrite = TRUE;
INPUT_RECORD InputRecord;
DWORD dwRecordsWriten;
InputRecord.EventType = KEY_EVENT;
InputRecord.Event.KeyEvent.bKeyDown = TRUE;
#ifdef UNICODE
InputRecord.Event.KeyEvent.uChar.UnicodeChar = L' ';
#else
InputRecord.Event.KeyEvent.uChar.AsciiChar = ' ';
#endif
BOOL ret = WriteConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsWriten);
ASSERT(ret);
}
void CConsole::EnableWrite()
{
m_blnDisableWrite = FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -