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

📄 console.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* $Id: Console.cpp 12803 2005-01-04 21:40:25Z narnaoud $
 *
 * regexpl - Console Registry Explorer
 *
 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

// Console.cpp: implementation of the CConsole class.
//
//////////////////////////////////////////////////////////////////////

#include "ph.h"
#include "Console.h"

#define TAB_WIDTH         8
#define MORE_STRING			_T("-- Press space to view more. Press q or Ctrl+break to cancel.--")
#define MORE_EMPTY_STRING	_T("                                                               ")

/*
TCHAR * _tcsnchr(const TCHAR *string, TCHAR ch, int count)
{
	while (count--)
	{
		if (*string == 0) return NULL;
		if (*string == ch) return const_cast <char *>(string);
		string++;
	}
	return NULL;
}*/


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CConsole::CConsole()
{
	m_hStdIn = INVALID_HANDLE_VALUE;
	m_hStdOut = INVALID_HANDLE_VALUE;
	m_blnInsetMode = TRUE;		// Insert
//	m_blnInsetMode = FALSE;		// Overwrite
	m_dwInsertModeCursorHeight = 15;
	m_dwOverwriteModeCursorHeight = 100;
//	m_Lines = 0;
	m_pchBuffer = NULL;
	m_pchBuffer1 = NULL;
	m_pchBuffer2 = NULL;
	m_pfReplaceCompletionCallback = NULL;
	m_blnMoreMode = TRUE;
	m_dwOldInputMode = 0;
	m_dwOldOutputMode = 0;
	m_blnOldInputModeSaved = FALSE;
	m_blnOldOutputModeSaved = FALSE;
}

CConsole::~CConsole()
{
	if (m_pchBuffer)
		delete m_pchBuffer;
	if (m_pchBuffer1)
		delete m_pchBuffer1;
	if (m_pchBuffer2)
		delete m_pchBuffer2;

	if (m_blnOldInputModeSaved)
		SetConsoleMode(m_hStdIn,m_dwOldInputMode);
	if (m_blnOldOutputModeSaved)
		SetConsoleMode(m_hStdOut,m_dwOldOutputMode);

	if (m_hStdIn != INVALID_HANDLE_VALUE)
		VERIFY(CloseHandle(m_hStdIn));
	if (m_hStdOut != INVALID_HANDLE_VALUE)
		VERIFY(CloseHandle(m_hStdOut));
}

BOOL CConsole::Write(const TCHAR *p, DWORD dwChars)
{
	if (m_hStdOut == INVALID_HANDLE_VALUE)
		return FALSE;
	if (m_hStdIn == INVALID_HANDLE_VALUE)
		return FALSE;
	if (p == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	DWORD dwCharsToWrite = (dwChars)?dwChars:_tcslen(p);
	DWORD dwCharsWrittenAdd = 0;
	BOOL ret = TRUE;
	while (dwCharsToWrite && (!m_blnDisableWrite))
	{
		switch(p[dwCharsWrittenAdd])
		{
		case _T('\n'):
			m_CursorPosition.Y++;
			m_CursorPosition.X = 0;
			break;
		case _T('\r'):
			dwCharsWrittenAdd++;
			dwCharsToWrite--;
			continue;
		case _T('\t'):
			do
			{
				if (!Write(_T(" "))) return FALSE;
			}
			while ((m_CursorPosition.X % TAB_WIDTH) && (!m_blnDisableWrite));
			dwCharsWrittenAdd++;
			dwCharsToWrite--;
			continue;
		default:
			{
				if (!WriteChar(p[dwCharsWrittenAdd])) return FALSE;
				m_CursorPosition.X++;
			}
		}
		if (m_CursorPosition.X == m_BufferSize.X)
		{
			m_CursorPosition.Y++;
			m_CursorPosition.X = 0;
		}
		if (m_CursorPosition.Y == m_BufferSize.Y)
		{
			ASSERT(m_CursorPosition.X == 0);
			SMALL_RECT Src;
			Src.Left = 0;
			Src.Right = (SHORT)(m_BufferSize.X-1);
			Src.Top = 1;
			Src.Bottom = (SHORT)(m_BufferSize.Y-1);
			CHAR_INFO ci;
#ifdef UNICODE
			ci.Char.UnicodeChar = L' ';
#else
			ci.Char.AsciiChar = ' ';
#endif
			ci.Attributes = 0;
			COORD Dest;
			Dest.X = 0;
			Dest.Y = 0;
			if (!ScrollConsoleScreenBuffer(m_hStdOut,&Src,NULL,Dest,&ci)) return FALSE;
			m_CursorPosition.Y--;
			m_LinesScrolled++;
		}
		if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
		VERIFY(WriteChar(_T(' ')));
		if ((m_blnMoreMode)&&(m_CursorPosition.X == 0))
		{
			m_Lines++;
			if (m_Lines >= m_BufferSize.Y-1)
			{
				ASSERT(m_Lines == m_BufferSize.Y-1);
				m_Lines = 0;
				VERIFY(WriteString(MORE_STRING,m_CursorPosition));
				VERIFY(FlushInputBuffer());

				CONSOLE_CURSOR_INFO cci;
				cci.bVisible = FALSE;
				cci.dwSize = 100;
				VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci));

				INPUT_RECORD InputRecord;
				DWORD dwRecordsReaded;
				while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE)
				{
					ASSERT(dwRecordsReaded == 1);
					if (dwRecordsReaded != 1)
						break;
					if (InputRecord.EventType != KEY_EVENT)
						continue;
					if (!InputRecord.Event.KeyEvent.bKeyDown)
						continue;

					if ((InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_CANCEL)||
						(InputRecord.Event.KeyEvent.wVirtualKeyCode == _T('Q')))
					{
						VERIFY(GenerateConsoleCtrlEvent(CTRL_C_EVENT,0));
						continue;
					}
#ifdef UNICODE
					TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar;
#else
					TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar;
#endif
					if (ch)
						break;
				}

				// delete "more" msg
				VERIFY(WriteString(MORE_EMPTY_STRING,m_CursorPosition));
				m_CursorPosition.X = 0;

				cci.bVisible = TRUE;
				cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
				VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci));
			}
		}
		dwCharsWrittenAdd++;
		dwCharsToWrite--;
	}
	return ret;
}

unsigned int CConsole::GetTabWidth()
{
  return TAB_WIDTH;
}

BOOL CConsole::SetTitle(TCHAR *p)
{
	return SetConsoleTitle(p);
}

BOOL CConsole::SetTextAttribute(WORD wAttributes)
{
	m_wAttributes = wAttributes;
	return TRUE;
}
/*
BOOL CConsole::SetInputMode(DWORD dwMode)
{
	return SetConsoleMode(m_hStdIn,dwMode);
}

BOOL CConsole::SetOutputMode(DWORD dwMode)
{
	return SetConsoleMode(m_hStdOut,dwMode);
}*/

BOOL CConsole::FlushInputBuffer()
{
	if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE;
	return FlushConsoleInputBuffer(m_hStdIn);
}

BOOL CConsole::ReadLine()
{
	if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE;
	if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE;
	if (m_dwBufferSize == 0)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	if (m_pchBuffer == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	if (m_pchBuffer1 == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	if (!FlushConsoleInputBuffer(m_hStdIn)) return FALSE;

	COORD FristCharCursorPosition = m_CursorPosition;
#define X_CURSOR_POSITION_FROM_OFFSET(ofs)	USHORT(((FristCharCursorPosition.X + ofs)%m_BufferSize.X))
#define Y_CURSOR_POSITION_FROM_OFFSET(ofs)	USHORT((FristCharCursorPosition.Y + (FristCharCursorPosition.X + ofs)/m_BufferSize.X))
//#define OFFSET_FROM_CURSOR_POSITION(pos)	((pos.Y-FristCharCursorPosition.Y)*m_BufferSize.X+pos.X-FristCharCursorPosition.X)

	DWORD dwRecordsReaded;
	DWORD dwCurrentCharOffset = 0;
	DWORD dwLastCharOffset = 0;
	BOOL ret;

	BOOL blnCompletionMode = FALSE;
//	unsigned __int64 nCompletionIndex = 0;
	unsigned long long nCompletionIndex = 0;
	DWORD dwCompletionOffset = 0;
	DWORD dwCompletionStringSize = 0;
	COORD CompletionPosition = FristCharCursorPosition;

	m_LinesScrolled = 0;
	BOOL blnOldMoreMode = m_blnMoreMode;
	m_blnMoreMode = FALSE;

	DWORD dwHistoryIndex = 0;

	INPUT_RECORD InputRecord;
	while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE)
	{
		ASSERT(dwRecordsReaded == 1);
		if (dwRecordsReaded != 1) return FALSE;
		if (InputRecord.EventType != KEY_EVENT) continue;
		if (!InputRecord.Event.KeyEvent.bKeyDown) continue;
#ifdef UNICODE
		TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar;
#else
		TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar;
#endif
KeyRepeat:
		if (m_LinesScrolled)
		{
			if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE;
			FristCharCursorPosition.Y = SHORT(FristCharCursorPosition.Y - m_LinesScrolled);
			if (m_LinesScrolled > CompletionPosition.Y) return FALSE;
			CompletionPosition.Y = SHORT(CompletionPosition.Y - m_LinesScrolled);
			m_LinesScrolled = 0;
		}
//		char Buf[1024];
//		sprintf(Buf,"wVirtualKeyCode = %u\nchar = %u\n\n",InputRecord.Event.KeyEvent.wVirtualKeyCode,ch);
//		OutputDebugString(Buf);

#ifndef NO_PASTE
		if ((ch == 0x16)&&(InputRecord.Event.KeyEvent.wVirtualKeyCode == 'V'))
		{
			goto Paste;
		}
		else
#endif
    if (ch == 0)
		{
#ifndef NO_PASTE
			if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_INSERT)
			{
				if (!(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED))
				{
					VERIFY(SetInsertMode(!m_blnInsetMode));
				}
				else
				{
					if (blnCompletionMode) blnCompletionMode = FALSE;

Paste:
					if (!IsClipboardFormatAvailable(
#ifdef UNICODE
						CF_UNICODETEXT
#else
						CF_TEXT
#endif
						)) 
						continue; 
					if (!OpenClipboard(NULL)) 
						continue; 
 
					const TCHAR *pch = NULL;

					HANDLE hglb = GetClipboardData(
#ifdef UNICODE
						CF_UNICODETEXT
#else
						CF_TEXT
#endif
						);
					if (hglb != NULL) 
					{ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -