?? console.h
字號:
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 + -