tconsole.cpp

来自「一个类似windows」· C++ 代码 · 共 1,009 行 · 第 1/3 页

CPP
1,009
字号
	} else if(dwDestOrg.Y < CON_TOP + iStartRow) {
		// Modify the scroll region (Paul Brannan 12/3/98)
		dwDestOrg.Y = CON_TOP + iStartRow;
		srScrollWindow.Top -= bUp;
	} else 	if(dwDestOrg.Y + (iEndRow-iStartRow+1) > CON_TOP + iEndRow) {
		// Modify the scroll region (Paul Brannan 12/3/98)
		srScrollWindow.Bottom -= bUp;
	}
	
	ScrollConsoleScreenBuffer(hConsole, &srScrollWindow,
		0, dwDestOrg, &ciChar);
}

// This allows us to clear the screen with an arbitrary character
// (Paul Brannan 6/26/98)
void TConsole::ClearScreen(char c) {
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
		(DWORD)(CON_LINES), Coord, &dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
		(DWORD)(CON_LINES), Coord, &dwWritten);
}

// Same as clear screen, but only affects the scroll region
void TConsole::ClearWindow(int iStartRow, int iEndRow, char c) {
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP + iStartRow};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
		(DWORD)(iEndRow-iStartRow+1), Coord, &dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
		(DWORD)(CON_LINES), Coord, &dwWritten);
}

// Clear from cursor to end of screen
void TConsole::ClearEOScreen(char c)
{
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y + 1};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
		(DWORD)(CON_HEIGHT - CON_CUR_Y), Coord, &dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
		(DWORD)(CON_LINES - CON_CUR_Y), Coord, &dwWritten);
	ClearEOLine();
}

// Clear from beginning of screen to cursor
void TConsole::ClearBOScreen(char c)
{
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS)*
		(DWORD)(CON_CUR_Y), Coord, &dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS)*
		(DWORD)(CON_CUR_Y), Coord, &dwWritten);
	ClearBOLine();
}

void TConsole::ClearLine(char c)
{
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_COLS),
		Coord, &dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_COLS),
		Coord, &dwWritten);
	GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
}

void TConsole::ClearEOLine(char c)
{
	DWORD dwWritten;
	COORD Coord = {CON_LEFT + CON_CUR_X, CON_TOP + CON_CUR_Y};
	FillConsoleOutputAttribute(hConsole, wAttributes,
		(DWORD)(CON_RIGHT - CON_CUR_X) +1, Coord, &dwWritten);
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_RIGHT - CON_CUR_X) +1,
		Coord, &dwWritten);
	GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
}

void TConsole::ClearBOLine(char c)
{
	DWORD dwWritten;
	COORD Coord = {CON_LEFT, CON_TOP + CON_CUR_Y};
	FillConsoleOutputCharacter(hConsole, c, (DWORD)(CON_CUR_X) + 1, Coord,
		&dwWritten);
	FillConsoleOutputAttribute(hConsole, wAttributes, (DWORD)(CON_CUR_X) + 1,
		Coord, &dwWritten);
	GetConsoleScreenBufferInfo(hConsole, &ConsoleInfo);
}


//	Inserts blank lines to the cursor-y-position
//	scrolls down the rest. CURSOR MOVEMENT (to Col#1) ???
void TConsole::InsertLine(int numlines)
{
	COORD		to;
	SMALL_RECT	from;
	SMALL_RECT	clip;
	CHAR_INFO		fill;
	int		acty;
	
	// Rest of screen would be deleted
	if ( (acty = GetCursorY()) >= CON_LINES - numlines ) {
		ClearEOScreen();    // delete rest of screen
		return;
	} /* IF */
	
	//	Else scroll down the part of the screen which is below the
	//	cursor.
	from.Left =		CON_LEFT;
	from.Top =		CON_TOP + (SHORT)acty;
	from.Right =	CON_LEFT + (SHORT)CON_COLS;
	from.Bottom =	CON_TOP + (SHORT)CON_LINES;
	
	clip = from;
	to.X = 0;
	to.Y = (SHORT)(from.Top + numlines);
	
	fill.Char.AsciiChar = ' ';
	fill.Attributes = 7; 		// WHICH ATTRIBUTES TO TAKE FOR BLANK LINE ??
	
	ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
} /* InsertLine */

//	Inserts blank characters under the cursor
void TConsole::InsertCharacter(int numchar)
{
	int		actx;
	SMALL_RECT	from;
	SMALL_RECT	clip;
	COORD			to;
	CHAR_INFO		fill;
	
	if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
		ClearEOLine();
		return;
	} /* IF */
	
	from.Left =		CON_LEFT + (SHORT)actx;
	from.Top =		CON_TOP + (SHORT)GetCursorY();
	from.Right =	CON_LEFT + (SHORT)CON_COLS;
	from.Bottom =	CON_TOP + (SHORT)from.Top;
	
	clip = from;
	to.X = (SHORT)(actx + numchar);
	to.Y = from.Top;
	
	fill.Char.AsciiChar = ' ';
	fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
	
	ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
} /* InsertCharacter */

// Deletes characters under the cursor
// Note that there are cases in which all the following lines should shift by
// a character, but we don't handle these.  This could break some
// VT102-applications, but it shouldn't be too much of an issue.
void TConsole::DeleteCharacter(int numchar)
{
	int		actx;
	SMALL_RECT	from;
	SMALL_RECT	clip;
	COORD			to;
	CHAR_INFO		fill;
	
	if ( (actx = GetCursorX()) >= CON_COLS - numchar ) {
		ClearEOLine();
		return;
	} /* IF */
	
	from.Left =		CON_LEFT + (SHORT)actx;
	from.Top =		CON_TOP + (SHORT)GetCursorY();
	from.Right =	CON_LEFT + (SHORT)CON_COLS;
	from.Bottom =	CON_TOP + from.Top;
	
	clip = from;
	to.X = (SHORT)(actx - numchar);
	to.Y = from.Top;
	
	fill.Char.AsciiChar = ' ';
	fill.Attributes = wAttributes; // WHICH ATTRIBUTES TO TAKE FOR BLANK CHAR ??
	
	ScrollConsoleScreenBuffer(hConsole, &from, &clip, to, &fill);
} /* DeleteCharacter */

void TConsole::SetRawCursorPosition(int x, int y) {
	if (x > CON_WIDTH)  x = CON_WIDTH;
	if (x < 0)			x = 0;
	if (y > CON_HEIGHT)	y = CON_HEIGHT;
	if (y < 0)			y = 0;
	COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
	SetConsoleCursorPosition(hConsole, Coord);
	
	// Update the ConsoleInfo struct (Paul Brannan 5/9/98)
	ConsoleInfo.dwCursorPosition.Y = Coord.Y;
	ConsoleInfo.dwCursorPosition.X = Coord.X;
	
	// bug fix in case we went too far (Paul Brannan 5/25/98)
	if(ConsoleInfo.dwCursorPosition.X < CON_LEFT)
		ConsoleInfo.dwCursorPosition.X = CON_LEFT;
	if(ConsoleInfo.dwCursorPosition.X > CON_RIGHT)
		ConsoleInfo.dwCursorPosition.X = CON_RIGHT;
	if(ConsoleInfo.dwCursorPosition.Y < CON_TOP)
		ConsoleInfo.dwCursorPosition.Y = CON_TOP;
	if(ConsoleInfo.dwCursorPosition.Y > CON_BOTTOM)
		ConsoleInfo.dwCursorPosition.Y = CON_BOTTOM;
}

// The new SetCursorPosition takes scroll regions into consideration
// (Paul Brannan 6/27/98)
void TConsole::SetCursorPosition(int x, int y) {
	if (x > CON_WIDTH)  x = CON_WIDTH;
	if (x < 0)			x = 0;
	if(iScrollEnd != -1) {
		if(y > iScrollEnd)		y = iScrollEnd;
	} else {
		if(y > CON_HEIGHT)		y = CON_HEIGHT;
	}
	if(iScrollStart != -1) {
		if(y < iScrollStart)	y = iScrollStart;
	} else {
		if(y < 0)				y = 0;
	}

	COORD Coord = {(short)(CON_LEFT + x), (short)(CON_TOP + y)};
	SetConsoleCursorPosition(hConsole, Coord);
	
	// Update the ConsoleInfo struct
	ConsoleInfo.dwCursorPosition.Y = Coord.Y;
	ConsoleInfo.dwCursorPosition.X = Coord.X;
}

void TConsole::MoveCursorPosition(int x, int y) {
	SetCursorPosition(CON_CUR_X + x, CON_CUR_Y + y);
}

void TConsole::SetExtendedMode(int iFunction, BOOL bEnable)
{
	// Probably should do something here...
	// Should change the screen mode, but do we need this?
}

void TConsole::SetScroll(int start, int end) {
	iScrollStart = start;
	iScrollEnd = end;
}

void TConsole::Beep() {
	if(ini.get_do_beep()) {
		if(!ini.get_speaker_beep()) printit("\a");
		else ::Beep(400, 100);
	}
}

void TConsole::SetCursorSize(int pct) {
	CONSOLE_CURSOR_INFO ci = {(pct != 0)?pct:1, pct != 0};
	SetConsoleCursorInfo(hConsole, &ci);
}

void saveScreen(CHAR_INFO *chiBuffer) {
	HANDLE hStdout;
	CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
	SMALL_RECT srctReadRect;
	COORD coordBufSize;
	COORD coordBufCoord;
	
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
	
    srctReadRect.Top = CON_TOP;    /* top left: row 0, col 0  */
    srctReadRect.Left = CON_LEFT;
    srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
    srctReadRect.Right = CON_RIGHT;
	
    coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
    coordBufSize.X = CON_RIGHT-CON_LEFT+1;
	
    coordBufCoord.X = CON_TOP;
    coordBufCoord.Y = CON_LEFT;
	
    ReadConsoleOutput(
		hStdout,        /* screen buffer to read from       */
		chiBuffer,      /* buffer to copy into              */
		coordBufSize,   /* col-row size of chiBuffer        */
		
		coordBufCoord,  /* top left dest. cell in chiBuffer */
		&srctReadRect); /* screen buffer source rectangle   */
}

void restoreScreen(CHAR_INFO *chiBuffer) {
	HANDLE hStdout;
	CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
	SMALL_RECT srctReadRect;
	COORD coordBufSize;
	COORD coordBufCoord;
	
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
	
	// restore screen
    srctReadRect.Top = CON_TOP;    /* top left: row 0, col 0  */
    srctReadRect.Left = CON_LEFT;
    srctReadRect.Bottom = CON_BOTTOM; /* bot. right: row 1, col 79 */
    srctReadRect.Right = CON_RIGHT;
	
    coordBufSize.Y = CON_BOTTOM-CON_TOP+1;
    coordBufSize.X = CON_RIGHT-CON_LEFT+1;
	
    coordBufCoord.X = CON_TOP;
    coordBufCoord.Y = CON_LEFT;
    WriteConsoleOutput(
        hStdout, /* screen buffer to write to    */
        chiBuffer,        /* buffer to copy from          */
        coordBufSize,     /* col-row size of chiBuffer    */
        coordBufCoord, /* top left src cell in chiBuffer  */
        &srctReadRect); /* dest. screen buffer rectangle */
	// end restore screen
    
}

CHAR_INFO* newBuffer() {
    CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
    CHAR_INFO * chiBuffer;
    chiBuffer = new CHAR_INFO[(CON_BOTTOM-CON_TOP+1)*(CON_RIGHT-CON_LEFT+1)];
	return chiBuffer;
}

void deleteBuffer(CHAR_INFO* chiBuffer) {
	delete[] chiBuffer;
}

⌨️ 快捷键说明

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