⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        // 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 + -