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

📄 console.h

📁 非常棒的VC入门课件
💻 H
📖 第 1 页 / 共 3 页
字号:
void CConsole::_ShowCursor(bool show)
{
	CONSOLE_CURSOR_INFO curInfo;
	GetConsoleCursorInfo(hOut, &curInfo);
	curInfo.bVisible = show;
	SetConsoleCursorInfo(hOut, &curInfo);
}

void CConsole::_OutText(char *str, int nch)
{
	int x, y;
	_GetCursorPos(&x, &y);
	_OutTextXY(x, y, str, nch);
}

void CConsole::_OutTextXY(int x, int y, char *str, int nch)
{
	_SetCursorPos(x, y);
	if (nch<0) nch = strlen(str);
	WriteConsole(hOut, str, nch, NULL, NULL);
}

void CConsole::_SaveSettings(void)
{
	nSaveColor[0]	= _GetBackColor();
	nSaveColor[1]	= _GetForeColor();
	_GetCursorPos(&nSavePos[0], &nSavePos[1]);
	CONSOLE_CURSOR_INFO curInfo;
	GetConsoleCursorInfo(hOut, &curInfo);
	bSaveShow = (curInfo.bVisible>0);
	rcSave = rcWindow;

	bSaved = true;
}

void CConsole::_LoadSettings(void)
{
	if (!bSaved) return;
	rcWindow = rcSave;
	_SetCursorPos(nSavePos[0], nSavePos[1]);
	_SetBackColor(nSaveColor[0]);
	_SetForeColor(nSaveColor[1]);
	_ShowCursor(bSaveShow);
	bSaved = false;
}

void CConsole::_SaveWindow(void)
{
	COORD pos = {0, 0};

	nMaxCols = rcWindow.Right - rcWindow.Left + 1;
	nMaxRows = rcWindow.Bottom - rcWindow.Top + 1;

	COORD size = {nMaxCols, nMaxRows};
	SMALL_RECT rc = rcWindow;
	ReadConsoleOutput(hOut, charInfo, size, pos, &rc); 
}

void CConsole::_SaveWindow(CHAR_INFO *buf)
{
	COORD pos = {0, 0};

	nMaxCols = rcWindow.Right - rcWindow.Left + 1;
	nMaxRows = rcWindow.Bottom - rcWindow.Top + 1;

	COORD size = {nMaxCols, nMaxRows};
	SMALL_RECT rc = rcWindow;
	ReadConsoleOutput(hOut, buf, size, pos, &rc); 
}

void CConsole::_PutWindow(int absX, int absY)
{
	if ((nMaxCols * nMaxRows) <= 0) return;
	COORD pos = {0, 0};
	COORD size = {nMaxCols, nMaxRows};
	SMALL_RECT rc = {absX, absY, absX+nMaxCols-1, absY+nMaxRows-1};
	WriteConsoleOutput(hOut, charInfo, size, pos, &rc);
}

void CConsole::_PutWindow(int absX, int absY, CHAR_INFO *buf)
{
	if ((nMaxCols * nMaxRows) <= 0) return;
	COORD pos = {0, 0};
	COORD size = {nMaxCols, nMaxRows};
	SMALL_RECT rc = {absX, absY, absX+nMaxCols-1, absY+nMaxRows-1};
	WriteConsoleOutput(hOut, buf, size, pos, &rc);
}

unsigned int CConsole::_GetKeyChar(void)
{
	INPUT_RECORD keyRec;
	DWORD res;

	unsigned char ch = 0;
	unsigned int vKeyCode = 0;

	ReadConsoleInput(hIn, &keyRec, 1, &res);
	if (keyRec.EventType == KEY_EVENT){
		if (keyRec.Event.KeyEvent.bKeyDown) {
			ch = keyRec.Event.KeyEvent.uChar.AsciiChar;
			vKeyCode = keyRec.Event.KeyEvent.wVirtualKeyCode;
		}
	}

	if (isprint(ch)) {
		vKeyCode = ch<<8;
	}
	return vKeyCode;
}

int CConsole::_GetMouse(int *mx, int *my, int *state)
{
	INPUT_RECORD mouseRec;
	DWORD res, flags = 0, btnState = 0; 
	COORD pos = {0, 0};
	int	  nButton = -1;

	ReadConsoleInput(hIn, &mouseRec, 1, &res);
	if (mouseRec.EventType == MOUSE_EVENT){
		flags = mouseRec.Event.MouseEvent.dwEventFlags;
		pos = mouseRec.Event.MouseEvent.dwMousePosition;
		btnState =  mouseRec.Event.MouseEvent.dwButtonState;
	}

	if (btnState == FROM_LEFT_1ST_BUTTON_PRESSED) nButton = 1;
	if (btnState == RIGHTMOST_BUTTON_PRESSED) nButton = 5;
	if (btnState == FROM_LEFT_2ND_BUTTON_PRESSED) nButton = 2;
	if (btnState == FROM_LEFT_3RD_BUTTON_PRESSED) nButton = 3;
	if (btnState == FROM_LEFT_4TH_BUTTON_PRESSED) nButton = 4;

	*state = 0;
	if (nButton>=0)	*state = 1;
	if (flags == DOUBLE_CLICK) *state = 2;
	if (flags == MOUSE_MOVED) nButton = 0;

	int x = pos.X - rcWindow.Left;  
	int y = pos.Y - rcWindow.Top;

	if (x<0) return -1;
	if (y<0) return -1;

	*mx =x;		*my = y;
	
	return nButton;
}

struct MENUITEM
{
	char itemName[100];
	char chItem;
	int  chPos;
	int	 itemPos;
} ;

class CConUI: public CConsole
{
public:
	CConUI();

	void _SetMainFrameTitle(char *str);
	// 设置主框架窗口的标题

	void _SetMultiInputTitle(char *str);
	// 设置_InputMultiBox的标题

	void _SetOptionsTitle(char *str);
	// 设置_GetOptions的标题

	char _MessageBox(char *caption, char *str, int mode = 0);	
	// 消息框,caption是消息框的标题,str只能包含\n转义符,mode是不同的配色方案,返回按键字符
	// 0: 灰色背景,白色双边框,黑色文本,不显示光标,用于一般信息显示
	// 1: 绿色背景,白色双边框,白色文本,不显示光标,用于带有询问的一般信息显示
	// 2: 青色背景,黄色双边框,黄色文本,显示光标,用于带有询问的一般警告信息显示,等待输入
	// 3: 红色背景,黄色双边框,黄色文本,显示光标,用于带有询问的严重警告信息显示,等待输入

	char* _InputBox(char *name, int x, int y, int nchars = 20, bool center = true);
	// 在(x, y)处显示一个输入框,name为提示文本,nchars是输入框内能显示的字符个数 
	// 当按回车键时,返回输入的字符串,否则返回NULL
	// 当居中显示时,x,y忽略

	bool _InputMultiBox(char **name, int x, int y, int length, char **str, int num, bool center = true);
	// 用于指定num个记录的输入, 当最后一个记录按ENTER键后,退出返回true
	// 按ESC时,退出返回flase,按TAB键在记录中选择输入
	// name为各个记录的提示文本,输入的内容由str返回
	// length为输入框的长度
	// 当居中显示时,x,y忽略

	int _GetOptions(char **str, int x, int y, int num, int *chpos = NULL, bool center = true);
	// 返回用户从num个项目中选择一个选项,0表示第一项,依次类推。若没有选择则返回-1
	// str指定选项内容,chpos指定相应的str中的选择字符,即当用户按下该字符时表示选中此项。
	// 当居中显示时,x,y忽略

	void _InitMainFrame( int nMode );
	// nMode表示主框架窗口标题栏、底部颜色、背景颜色,边框颜色、边框模式等方案
	// nMode	背景颜色	标题栏颜色		底部颜色		边框颜色	边框模式
	//  0		 深灰(8)	 蓝(1)白(15)	 灰(7)黑(0)		 灰(7)		 上单余双
	//  1		 蓝(1)		 灰(7)黑(0)		 灰(7)黑(0)		 白(15)		 上单余双
	//  2		 绿(2)		 蓝(1)白(15)	 灰(7)黑(0)		 白(15)		 上单余双
	//  3		 深灰(8)	 蓝(1)白(15)	 灰(7)黑(0)		 灰(7)		 下单余双
	//  4		 蓝(1)		 灰(7)黑(0)		 灰(7)黑(0)		 白(15)		 下单余双
	//  5		 绿(2)		 蓝(1)白(15)	 灰(7)黑(0)		 白(15)		 下单余双
	//  6		 深灰(8)	 蓝(1)白(15)	 灰(7)黑(0)		 灰(7)		 左右双余单
	//  7		 蓝(1)		 灰(7)黑(0)		 灰(7)黑(0)		 白(15)		 左右双余单
	//  8		 绿(2)		 蓝(1)黑(0)		 灰(7)黑(0)		 白(15)		 左右双余单

private:
	int m_nMenuItemNum;		// 选择的菜单项
	MENUITEM menuItem[40];	// 菜单项

	// 下面的颜色用于界面配色
	int m_nControlColor[2];		// 控件颜色对
	int m_nFrameColor[2];		// 框架颜色对
	int m_nMenuColor[3];		// 菜单颜色对

	char m_InputChars[256];
	char m_strMultiTitle[100];
	char m_strOptionsTitle[100];
	char m_strMainFrameTitle[100];	// 主框架标题
	int	 m_nCharNum;		
	char m_MultiInputChars[40][256];
	int	 m_nMultiCharNum[40];
	int  m_nMultiNum;
	int _InputLine(int x, int y, int nlength, int bkcolor, int focolor,
			char *str, int *nchars);
	//返回0表示OK,-1表示ESC, 1表示TAB, 2表示UP, 3表示DOWN
	void _CalCenterWindow(int *x1, int *y1, int *x2, int *y2);
	// 重新计算窗口,使得窗口在屏幕居中
};

// CConUI类的实现
CConUI::CConUI()
	:m_nCharNum(0), m_nMultiNum(0)
{  
	strcpy(m_strMultiTitle, " Input ");
	strcpy(m_strOptionsTitle, " Select ");
	strcpy(m_strMainFrameTitle, " Main ");	// 设置默认的主框架标题
	m_nFrameColor[0] = 7;		m_nFrameColor[1] = 15;
	m_nControlColor[0] = 7;		m_nControlColor[1] = 0;
	m_nMenuColor[0] = 0;		m_nMenuColor[1] = 15;		m_nMenuColor[2] = 4;
}

void CConUI::_SetMainFrameTitle(char *str)
{
	strcpy(m_strMainFrameTitle, str);
}

void CConUI::_SetMultiInputTitle(char *str)
{
	strcpy(m_strMultiTitle, str);
}

void CConUI::_SetOptionsTitle(char *str)
{
	strcpy(m_strOptionsTitle, str);
}

void CConUI::_InitMainFrame( int nMode )
{
	if (nMode<0) nMode = -nMode;
	char	strBottom[] = "TextMode Interface Designed By DingYouHe, 4/28/2006";

	// 保存原来的设置
	_SaveSettings();

	// 获取控制台窗口大小
	int nMaxX, nMaxY;
	_GetConwinSize( &nMaxX, &nMaxY );

	// 构造颜色方案和边框方案
	int nBoxMode, nBoxColor, nBottomColor[2], nTitleColor[2], nBackColor;
	nBoxMode = nMode/3 + 3;
	int nIndex = nMode % 3;
	switch (nIndex) {
		case 0:		
			nBoxColor = 7;		
			nBottomColor[0] = 7;	nBottomColor[1] = 0;
			nTitleColor[0] = 1;		nTitleColor[1] = 15;
			nBackColor = 8;
			break;
		case 1:		
			nBoxColor = 15;		
			nBottomColor[0] = 7;	nBottomColor[1] = 0;
			nTitleColor[0] = 7;		nTitleColor[1] = 0;
			nBackColor = 1;
			break;
		case 2:		
			nBoxColor = 15;		
			nBottomColor[0] = 7;	nBottomColor[1] = 0;
			nTitleColor[0] = 1;		nTitleColor[1] = 15;
			nBackColor = 2;
			break;
	}

	_DefineWindow( 0, 0, nMaxX, nMaxY );

	// 填充整个框架
	_SetBackColor( nBackColor );
	_FillBox( 0, 0, nMaxX, nMaxY );

	// 绘制标题
	_SetBackColor(nTitleColor[0]);
	_SetForeColor(nTitleColor[1]);
	_FillBox( 0, 0, nMaxX, 1 );
	_OutTextXY((nMaxX - strlen(m_strMainFrameTitle))/2, 0, m_strMainFrameTitle);

	// 绘制底部
	_SetBackColor(nBottomColor[0]);
	_SetForeColor(nBottomColor[1]);
	_FillBox( 0, nMaxY-1, nMaxX, 1 );
	_OutTextXY(nMaxX - strlen(strBottom)-10, nMaxY-1, strBottom);
	
	// 绘制边框
	_SetBackColor(nBackColor);
	_SetForeColor(nBoxColor);
	_DrawBox( 0, 1, nMaxX, nMaxY-2, nBoxMode );

	// 恢复原来的设置
	_LoadSettings();
	_DefineWindow( 1, 2, nMaxX-1, nMaxY-3 );
	_SetBackColor( nBackColor );
	_SetForeColor(15);
}

bool CConUI::_InputMultiBox(char **name, int x, int y, int length, char **str, int num, bool center)
{
	if (num>40) num = 40;

	CHAR_INFO buf[100*40];
	// 计算最长提示文本的字符个数
	unsigned int nNameSize = 0;
	for (int i=0; i<num; i++) {
		if (nNameSize<strlen(name[i])) nNameSize = strlen(name[i]);
		m_nMultiCharNum[i] = 0;
	}

	// 计算所需要的窗口大小
	int x1, x2, y1, y2;
	x1 = x;		y1 = y;
	x2 = x1 + nNameSize + length + 4;
	y2 = y1 + num*3 + 1;

	if (center)
		_CalCenterWindow(&x1, &y1, &x2, &y2);

	_SaveSettings();
	_DefineWindow(x1, y1, x2+1, y2+1);	// 重新定义窗口
	_SaveWindow(buf);
	_DefineWindow(x1+1, y1+1, x2+1, y2+1);	// 重新定义窗口
	_SetBackColor(8);
	_FillBox(0,0, x2-x1+1, y2-y1+1,false);  // 阴影
	_DefineWindow(x1, y1, x2, y2);	// 重新定义窗口

	// 绘制窗口
	_SetBackColor(m_nFrameColor[0]);
	_SetForeColor(m_nFrameColor[1]);
	_ClearWindow();
	_DrawBox(0, 0, x2-x1+1, y2-y1+1, 2);

	int posX, posY;
	for (i=1; i<=num; i++) {
		int strSize = strlen(name[i-1]);
		posX = nNameSize - strSize + 2;
		posY = 3*i - 1;
		_OutTextXY(posX, posY, name[i-1], strSize);
		_DrawBox(nNameSize+2, posY-1, length+1, 3);
	}

	_OutTextXY(3, 0, m_strMultiTitle);

	_LoadSettings();
	bool bRes = false;

	// 一些初始化
	m_nCharNum = 0;
	m_nMultiNum = num;
	int nMultiPC = 0;		// 记录索引
	posX = x2 - length - 1;
	for (;;)
	{
		posY = y1 + 2 + nMultiPC * 3;

		int nRes = _InputLine(posX, posY, length-1, m_nControlColor[0], m_nControlColor[1], 
				m_MultiInputChars[nMultiPC], &m_nMultiCharNum[nMultiPC]);
		if (nRes == -1) // 按下ESC键,退出
			break;
		if ((nRes == 0)&&(nMultiPC == (num-1))) 
		{
			bRes = true;
			break;
		} 
		if (nRes == 2) //UP
			nMultiPC--;
		else
			nMultiPC++;

		if (nMultiPC<0) nMultiPC = num-1;
		if (nMultiPC>(num-1))	nMultiPC = 0;
		m_nCharNum = m_nMultiCharNum[nMultiPC];
		strncpy(m_InputChars, m_MultiInputChars[nMultiPC], m_nCharNum);
	}

	_PutWindow(x1, y1, buf);
	if (bRes) {		// 返回字符串
		for (i=0; i<num; i++){
			int n = m_nMultiCharNum[i];
			*str = new char[n+1];
			strncpy(*str, m_MultiInputChars[i], n);
			(*str)[n] = '\0';
			str++;
		}
	} else
	{
		for (i=0; i<num; i++){
			*str = new char[1];
			strcpy(*str, "");
			str++;
		}
	}
	return bRes;
}

char CConUI::_MessageBox(char *caption, char *str, int mode)
{
	char	chRes;
	int		chPos[40];
	unsigned int nNum = 1;
	
	// 记录str中\n字符的位置
	chPos[0] = 0;
	for (unsigned int i=0; i<strlen(str); i++) 
	{
		if (str[i]=='\n') {
			chPos[nNum] = i+1;
			nNum++;
		}
	} 
	chPos[nNum] = i;

	// 计算最长行的字符长度
	int nSize = 0;
	for (i=0; i<nNum; i++) {
		if (nSize < (chPos[i+1] - chPos[i] + 1))

⌨️ 快捷键说明

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