您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页c++学生管理系统

c++学生管理系统

来源:意榕旅游网
// Student.cpp : Defines the entry point for the console application. //

#include \"stdafx.h\"

#include \"console.h\" #include \"student.h\" #include \"studentui.h\"

CStudentUI theUI;

CStudentFile theFile(\"student.dat\");

// 定义命令函数

void DoAddRec(void); void DoDelRec(void); void DoListAllRec(void); void DoFindRec(void); void main() { const int nItemNum = 7; char *strItem[nItemNum] = { \"Add a student data record\ \"Delete a student data record\ \"-\ \"List all data records\ \"Find a student data record\ \"-\ \"Exit\" }; theUI._SetOptionsTitle(\" Main Menu \"); for (;;) { int nIndex = theUI._GetOptions(strItem,0,0,nItemNum); switch(nIndex) { case 0: // Add a student data record DoAddRec(); break; case 1: // Delete a student data record DoDelRec(); break; case 2: // List all data records DoListAllRec(); break; case 3: // Find a student data record DoFindRec(); break; break; case 4: // Exit return; } }

}

void DoAddRec(void) { CStudentRec rec; if ( theUI.InputStuRec( rec ) ) { theFile.Add( rec ); DoListAllRec(); } }

void DoDelRec(void) { CStudentRec rec; char strID[80], str[80]=\" No find the record of \"; strcpy(strID, theUI._InputBox( \" Input Deleted Student ID \ if (strID) { int nIndex = theFile.Seek( strID, rec ); if (nIndex>=0) { theFile.Delete( strID ); DoListAllRec(); } else { strcat( str, strID ); strcat( str, \" !\" ); theUI._MessageBox(\" Notice \ } } }

void DoListAllRec(void) { int nCount = theFile.GetRecCount(); CStudentRec *stu; stu = new CStudentRec[nCount]; theFile.GetStuRec( stu ); theUI.DispStuRecs( stu, nCount ); delete [nCount]stu; }

void DoFindRec(void) { CStudentRec rec; char strID[80], str[80]=\" No find the record of \"; strcpy(strID, theUI._InputBox( \" Input Finded Student ID \ if (strID) { int nIndex = theFile.Seek( strID, rec ); if (nIndex>=0) theUI.DispStuRecs( &rec, 1 );

else { strcat( str, strID ); strcat( str, \" !\" ); theUI._MessageBox(\" Notice \ } } }

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #include #include #include #include class CStudentRec {

public: CStudentRec(){chFlag = 'N';}; // 默认构造函数 ~CStudentRec(){}; // 默认析构函数 friend ostream& operator<< ( ostream& os, CStudentRec& stu ); friend istream& operator>> ( istream& is, CStudentRec& stu ); CStudentRec& operator = (CStudentRec &stu) // 赋值运算符重载 { strncpy(strName, stu.strName, 20); strncpy(strID, stu.strID, 10); for (int i=0; i<3; i++) fScore[i] = stu.fScore[i]; fAve = stu.fAve; chFlag = stu.chFlag; return *this; } char chFlag; // 标志,'A'表示正常,'N'表示空 char strName[20]; // 姓名 char strID[10]; // 学号 float fScore[3]; // 三门成绩 float fAve; // 总平均分 };

// CStudentRec类的实现

ostream& operator<< ( ostream& os, CStudentRec& stu ) { os.write(&stu.chFlag, sizeof(char)); os.write(stu.strName, sizeof(stu.strName)); os.write(stu.strID, sizeof(stu.strID)); os.write((char *)stu.fScore, sizeof(float)*3);

os.write((char *)&stu.fAve, sizeof(float)); return os; }

istream& operator>> ( istream& is, CStudentRec& stu ) { char name[20],id[10]; is.read(&stu.chFlag, sizeof(char)); is.read(name, sizeof(name)); is.read(id, sizeof(id)); is.read((char*)stu.fScore, sizeof(float)*3); is.read((char*)&stu.fAve, sizeof(float)); strncpy(stu.strName, name, sizeof(name)); strncpy(stu.strID, id, sizeof(id)); return is; }

class CStudentFile {

public: CStudentFile(char* filename); ~CStudentFile(); void Add(CStudentRec stu); // 添加记录 void Delete(char* id); // 删除学号为id的记录 void Update(int nRec, CStudentRec stu); // 更新记录号为nRec的内容,nRec从0开始 int Seek(char* id, CStudentRec &stu); // 按学号查找, 返回记录号,-1表示没有找到 int GetRecCount(void); // 获取文件中的记录数 int GetStuRec( CStudentRec* data ); // 获取所有记录,返回记录数 private: char* strFileName; // 文件名 };

// CStudentFile类的实现

CStudentFile::CStudentFile(char* filename) { strFileName = new char[strlen(filename)+1]; strcpy(strFileName, filename); }

CStudentFile::~CStudentFile() { if (strFileName) delete []strFileName; }

void CStudentFile::Add(CStudentRec stu) { // 打开文件用于添加 fstream file(strFileName, ios::out|ios::app|ios::binary );

file<void CStudentFile::Delete(char *id) { CStudentRec temp; int nDel = Seek(id, temp); if (nDel<0) return; // 设置记录中的chFlag为'N' temp.chFlag = 'N'; Update( nDel, temp ); }

void CStudentFile::Update(int nRec, CStudentRec stu) { fstream file(strFileName, ios::in|ios::out|ios::binary); // 二进制读写方式 if (!file) { cout<<\"the \"<int CStudentFile::Seek(char* id, CStudentRec& stu) // 按学号查找 { int nRec = -1; fstream file(strFileName, ios::in|ios::nocreate); // 打开文件用于只读 if (!file) { cout<<\"the \"<>stu; if ((strcmp(id, stu.strID) == 0) && (stu.chFlag == 'A')){ nRec = i; break; } i++; } file.close(); return nRec; }

int CStudentFile::GetRecCount(void)

{ fstream file(strFileName, ios::in|ios::nocreate); // 打开文件用于只读 if (!file) { cout<<\"the \"<>data; if (data.chFlag == 'A') nRec++; } file.close(); return nRec; }

int CStudentFile::GetStuRec( CStudentRec* data) { fstream file(strFileName, ios::in|ios::nocreate); // 打开文件用于只读 if (!file) { cout<<\"the \"<>stu; if (stu.chFlag == 'A') { data[nRec] = stu; nRec++; } } file.close(); return nRec; }

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ // 文件studentui.h中的内容 class CStudentUI: public CConUI {

public: CStudentUI();

bool InputStuRec(CStudentRec &stu); // 通过键盘输入记录 void DispStuRecs(CStudentRec *stu, int nNum); // 显示nNum个记录 private: void DispListHead(int nRow = 0); // 显示表头 };

CStudentUI::CStudentUI() { _SetMainFrameTitle(\"Management For The Student Scores\"); _InitMainFrame(7); DispListHead(); }

bool CStudentUI::InputStuRec(CStudentRec &stu) { bool bRes = false; char *str[5] = {\"Name:\ _SetMultiInputTitle( \"Input student record data\" ); bRes = _InputMultiBox(str, 0, 0, 20, str, 5); if (bRes){ strncpy(stu.strName, str[0], 20); strncpy(stu.strID, str[1], 10); stu.fAve = (float)0.0; for (int i=0; i<3; i++) { stu.fScore[i] = (float)atof(str[i+2]); stu.fAve += stu.fScore[i]; } stu.fAve = float(stu.fAve/3.0); stu.chFlag = 'A'; } return bRes; }

void CStudentUI::DispListHead(int nRow) { int nSizeX, nSizeY; _GetWindowSize(&nSizeX, &nSizeY); // 获得窗口的大小 _SaveSettings(); _SetBackColor(15); // 背景色为白色 _SetForeColor(0); // 文本色为黑色 _FillBox(0, nRow, nSizeX-1, 1, false); // 画背景水平条 _SetCursorPos(0, nRow); cout.setf(ios::left); cout<_GetConwinSize(&nSizeX, &nSizeY); // 获得控制台窗口的大小 _DefineWindow(1, 3, nSizeX-2, nSizeY-3); // 重新定义窗口 }

void CStudentUI::DispStuRecs(CStudentRec *stu, int nNum) { // 每屏显示nMaxLine个,若nNum>nMaxLine, // 则可按PageUp和PageDown向上和向下翻页 // 若nNum>nMaxLine,则按ESC键退出 const int nMaxLine = 20; int nStart, nEnd, nPage = 0, nMaxPages, nRow=0; nMaxPages = (nNum-1)/nMaxLine; // 最大可显示的页数 unsigned int ch; int nSizeX, nSizeY, nBkColor, nForeColor; for (;;) { nStart = nPage * nMaxLine; nEnd = nStart + nMaxLine; if (nEnd>=nNum) nEnd = nNum; nRow = 0; _ClearWindow(); for (int i=nStart; i_SetForeColor( nBkColor ); cout<<\" \"; cout.flush(); // 恢复原来的颜色设置 _SetBackColor( nBkColor ); _SetForeColor( nForeColor ); for(;;) { ch = _GetKeyChar(); // 当按下ESC退出 if (ch == VK_ESCAPE) return; if (ch == VK_PRIOR ) { // PAGEUP键 nPage--; if (nPage<0) nPage = 0; break; } if (ch == VK_NEXT ) { // PAGEDOWN键 nPage++; if (nPage>nMaxPages) nPage = nMaxPages; break; } } } } }

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /*

用于控制台窗口界面设计,版本1.0 2002 - 2003

2006.5

(1) 添加了控制台窗口的字体设计, (2) 添加了边框型式, (3) 添加主框架窗口的界面 */

#include #include #include #include #include

#include

typedef struct CONSOLE_FONT { DWORD index; COORD dim;

} *PCONSOLE_FONT;

typedef BOOL *GetConsoleFontInfoFunc)(HANDLE,BOOL,DWORD,PCONSOLE_FONT); typedef COORD (WINAPI *GetConsoleFontSizeFunc)(HANDLE, DWORD); typedef BOOL (WINAPI *GetCurrentConsoleFontFunc)(HANDLE, PCONSOLE_FONT);

typedef DWORD (WINAPI *GetNumberOfConsoleFontsFunc)();

typedef BOOL (WINAPI *SetConsoleFontFunc)(HANDLE, DWORD);

GetConsoleFontInfoFunc pGetConsoleFontInfo; GetConsoleFontSizeFunc pGetConsoleFontSize;

GetCurrentConsoleFontFunc pGetCurrentConsoleFont;

GetNumberOfConsoleFontsFunc pGetNumberOfConsoleFonts; SetConsoleFontFunc pSetConsoleFont;

PCONSOLE_FONT fonts = NULL;

int GetAvailableFonts(HANDLE hCon,PCONSOLE_FONT *fonts) { int fontcount = pGetNumberOfConsoleFonts(); *fonts = new CONSOLE_FONT[fontcount]; pGetConsoleFontInfo(hCon,0,fontcount,*fonts);

return fontcount; }

BOOL SetFont(HANDLE hCon,int index) { if (!pSetConsoleFont(hCon,index)) { return FALSE; }

return TRUE; }

BOOL Init() {

HINSTANCE hLib = NULL; BOOL bRet = TRUE;

hLib = LoadLibrary(\"KERNEL32.DLL\");

(WINAPI BOOL,

if (hLib == NULL) { return FALSE; }

pGetConsoleFontInfo = (GetConsoleFontInfoFunc)GetProcAddress(hLib,\"GetConsoleFontInfo\"); pGetConsoleFontSize = (GetConsoleFontSizeFunc)GetProcAddress(hLib,\"GetConsoleFontSize\"); pGetCurrentConsoleFont = (GetCurrentConsoleFontFunc)GetProcAddress(hLib,\"GetCurrentConsoleFont\"); pGetNumberOfConsoleFonts = (GetNumberOfConsoleFontsFunc)GetProcAddress(hLib,\"GetNumberOfConsoleFonts\"); pSetConsoleFont = (SetConsoleFontFunc)GetProcAddress(hLib,\"SetConsoleFont\");

return bRet; }

class CConsole {

public: CConsole(); ~CConsole(); void _ClearWindow(void); // 清除当前窗口文本,并将光标移至左上角,即位置(0,0) void _DefineWindow(int left, int top, int right, int bottom); // 重新定义一个窗口,使得所有操作都与这个窗口有关 void _GetConwinSize(int *sizex, int *sizey); // 返回控制台窗口的大小 void _GetWindowSize(int *sizex, int *sizey); // 返回当前窗口的大小 void _SaveWindow(void); // 将当前窗口内容保存到内存中 void _SaveWindow(CHAR_INFO *buf); // 将当前窗口内容保存到指定内存中 void _PutWindow(int absX, int absY); // 将内存的内容写到指定位置处,(absX,absY)是绝对坐标 void _PutWindow(int absX, int absY, CHAR_INFO *buf); // 将指定内容写到指定位置处,(absX,absY)是绝对坐标 void _DrawBox(int x, int y, int length, int height, int mode = 0); // 在指定位置(x, y)绘制一个长为length,宽为height的框, // 当mode为0是单线,1为双线,2为混合,其它为单线

void _FillBox(int x, int y, int length, int height, bool solid = true);

// 填充指定范围的区域,若solid为true则擦除原来区域内容, 否则不擦除 void _DrawCharLine(int x, int y, int length, char ch);

// 在指定位置(x, y)绘制一个长为length字符线条,字符由ch指定 void _SaveSettings(void); void _LoadSettings(void);

// 保存当前的属性:光标、颜色和窗口 // 恢复_SaveSettings保存的属性

void _ShowCursor(bool show = true); // 显示/隐藏光标 void _OutText(char *str, int nch = -1); // 在当前光标处输出nch个字符 void _OutTextXY(int x, int y, char *str, int nch = -1); // 在指定位置处输出nch个字符 void _SetCursorPos(int x, int y); void _GetCursorPos(int *x, int *y); void _SetBackColor(int color); int _GetBackColor(void); void _SetForeColor(int color); int _GetForeColor(void); // 当color = 0 表示 黑色 // 当color = 1 表示 蓝色 // 当color = 2 表示 绿色 // 当color = 3 表示 青色 // 当color = 4 表示 红色 // 当color = 5 表示 洋红 // 当color = 6 表示 综色 // 当color = 7 表示 淡灰 // 当color = 8 表示 深灰 // 当color = 9 表示 淡蓝 // 当color = 10 表示 淡绿 // 当color = 11 表示 淡青 // 当color = 12 表示 淡红 // 当color = 13 表示 淡洋红 // 当color = 14 表示 黄色 // 当color = 15 表示 白色

// 将光标移动到指定位置 // 获取当前光标的位置

// 设置当前背景色 // 获取当前背景色 // 设置当前前景色 // 获取当前前景色

unsigned int _GetKeyChar(void); // 返回用户按键的字符,不等待,没有按键时返回0, // 若是非打印字符,返回虚拟键码 int _GetMouse(int *mx, int *my, int *state);

// 获取鼠标位置(*mx, *my),鼠标按钮操作状态*state, 1时为单击,2时为双击 // 返回鼠标操作的按钮,5为最右键,1为最左键,2为第2个键,依次类推,一直到4 // 没有鼠标信息或不在当前窗口范围时返回-1,没有按下鼠标按钮,返回0

private: HANDLE hOut; // 输出句柄 HANDLE hIn; // 输入句柄 SMALL_RECT rcWindow; // 窗口 WORD bkColor[16]; // 背景颜色 WORD foColor[16]; // 前景颜色 int bkColorIndex, foColorIndex; // 颜色索引值 int nSaveColor[2]; // 保存颜色 int nSavePos[2]; // 保存光标位置 bool bSaveShow; // 保存光标是否显示 SMALL_RECT rcSave; // 保存窗口 bool bSaved; // 是否可以调用_LoadSettings CHAR_INFO charInfo[100*40]; // 保存窗口内容 unsigned int nMaxCols, nMaxRows; // 最大的行和列 };

// CConsole类实现代码 CConsole::CConsole() { hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄 hIn = GetStdHandle(STD_INPUT_HANDLE); // 获取标准输入设备句柄

// 设置默认字体 PCONSOLE_FONT fonts = NULL;

HANDLE hConsole = GetStdHandle( STD_ERROR_HANDLE ); Init();

int count = GetAvailableFonts(hConsole,&fonts); SetFont(hConsole,fonts[count-1].index); SetConsoleOutputCP(437); // 设置代码页 SMALL_RECT rc = {0,0, 80-1, 25-1}; rcWindow = rc; // 定义默认的窗口大小 COORD size = {80, 25}; SetConsoleScreenBufferSize(hOut,size); // 设置缓冲区大小 SetConsoleWindowInfo(hOut,true ,&rc); // 显示全部控制台窗口

// 定义颜色 foColor[0] = bkColor[0] = 0; foColor[1] = FOREGROUND_BLUE; foColor[2] = FOREGROUND_GREEN; foColor[3] = FOREGROUND_BLUE | FOREGROUND_GREEN; foColor[4] = FOREGROUND_RED; foColor[5] = FOREGROUND_RED | FOREGROUND_BLUE; foColor[6] = FOREGROUND_RED | FOREGROUND_GREEN; foColor[7] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; bkColor[1] = BACKGROUND_BLUE; bkColor[2] = BACKGROUND_GREEN; bkColor[3] = BACKGROUND_BLUE | BACKGROUND_GREEN; bkColor[4] = BACKGROUND_RED; bkColor[5] = BACKGROUND_RED | BACKGROUND_BLUE; bkColor[6] = BACKGROUND_RED | BACKGROUND_GREEN; bkColor[7] = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; for (int i=0; i<=7; i++) { foColor[i+8] = foColor[i] + FOREGROUND_INTENSITY; bkColor[i+8] = bkColor[i] + BACKGROUND_INTENSITY; } bkColorIndex = 15; // 白色 foColorIndex = 0; // 黑色 SetConsoleTextAttribute(hOut, bkColor[bkColorIndex]|foColor[foColorIndex]); _ClearWindow(); _SetCursorPos(0, 0); bSaved = false; nMaxCols = nMaxRows = 0; }

CConsole::~CConsole() { CloseHandle(hOut); // 关闭标准输出设备句柄 CloseHandle(hIn); // 关闭标准输入设备句柄 }

void CConsole::_DrawCharLine(int x, int y, int length, char ch) { COORD pos = {rcWindow.Left + x, rcWindow.Top + y};

CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); WORD att = bInfo.wAttributes; for (int i = 0; ivoid CConsole::_DrawBox(int x, int y, int length, int height, int mode) { SMALL_RECT rc; rc.Left = rcWindow.Left + x; rc.Top = rcWindow.Top + y; rc.Right = rc.Left + length; rc.Bottom = rc.Top + height; char chBox[7]; if (mode>5) mode = 0; if (mode == 0) { // 单线 chBox[0] = (char)0xda; // 左上角点 chBox[1] = (char)0xbf; // 右上角点 chBox[2] = (char)0xc0; // 左下角点 chBox[3] = (char)0xd9; // 右下角点 chBox[4] = (char)0xc4; // 水平 chBox[5] = (char)0xc4; // 水平 chBox[6] = (char)0xb3; // 坚直 } else if (mode == 1){ // 双线 chBox[0] = (char)0xc9; // 左上角点 chBox[1] = (char)0xbb; // 右上角点 chBox[2] = (char)0xc8; // 左下角点 chBox[3] = (char)0xbc; // 右下角点 chBox[4] = (char)0xcd; // 水平 chBox[5] = (char)0xcd; // 水平 chBox[6] = (char)0xba; // 坚直 } else if (mode == 2){ // 混合, 上双余单 chBox[0] = (char)0xd5; // 左上角点 chBox[1] = (char)0xb8; // 右上角点 chBox[2] = (char)0xc0; // 左下角点 chBox[3] = (char)0xd9; // 右下角点 chBox[4] = (char)0xcd; // 上水平

chBox[5] = (char)0xc4; // 下水平 chBox[6] = (char)0xb3; // 坚直 } else if (mode == 3){ // 混合, 上单双余 chBox[0] = (char)0xd6; // 左上角点 chBox[1] = (char)0xb7; // 右上角点 chBox[2] = (char)0xc8; // 左下角点 chBox[3] = (char)0xbc; // 右下角点 chBox[4] = (char)0xc4; // 上水平 chBox[5] = (char)0xcd; // 下水平 chBox[6] = (char)0xba; // 坚直 } else if (mode == 4){ // 混合, 下单余双 chBox[0] = (char)0xc9; // 左上角点 chBox[1] = (char)0xbb; // 右上角点 chBox[2] = (char)0xd3; // 左下角点 chBox[3] = (char)0xbd; // 右下角点 chBox[4] = (char)0xcd; // 上水平 chBox[5] = (char)0xc4; // 下水平 chBox[6] = (char)0xba; // 坚直 } else if (mode == 5){ // 混合, 左右双余单 chBox[0] = (char)0xd6; // 左上角点 chBox[1] = (char)0xb7; // 右上角点 chBox[2] = (char)0xd3; // 左下角点 chBox[3] = (char)0xbd; // 右下角点 chBox[4] = (char)0xc4; // 上水平 chBox[5] = (char)0xc4; // 下水平 chBox[6] = (char)0xba; // 坚直 } CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); WORD att = bInfo.wAttributes; COORD pos = {rc.Left, rc.Top}; WriteConsoleOutputAttribute(hOut, &att, 1, pos, NULL); WriteConsoleOutputCharacter(hOut, &chBox[0], 1, pos, NULL); for (pos.X = rc.Left + 1; pos.XWriteConsoleOutputAttribute(hOut, &att, 1, pos, NULL); WriteConsoleOutputCharacter(hOut, &chBox[1], 1, pos, NULL); for (pos.Y = rc.Top+1; pos.Yvoid CConsole::_FillBox(int x, int y, int length, int height, bool solid) { SMALL_RECT rc; rc.Left = rcWindow.Left + x; rc.Top = rcWindow.Top + y; rc.Right = rc.Left + length; rc.Bottom = rc.Top + height; CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); WORD att = bInfo.wAttributes; COORD pos = {rc.Left, rc.Top}; unsigned long sizeLine = rc.Right - rc.Left; for (pos.Y=rc.Top; pos.Yif (solid) FillConsoleOutputCharacter(hOut, ' ', sizeLine, pos, NULL); } }

void CConsole::_ClearWindow(void) { CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); WORD att = bInfo.wAttributes; COORD pos = {rcWindow.Left, rcWindow.Top}; unsigned long sizeLine = rcWindow.Right - rcWindow.Left + 1; for (pos.Y=rcWindow.Top; pos.Y<=rcWindow.Bottom; pos.Y++) { FillConsoleOutputAttribute(hOut, att, sizeLine, pos, NULL); FillConsoleOutputCharacter(hOut, ' ', sizeLine, pos, NULL); } }

void CConsole::_DefineWindow(int left, int top, int right, int bottom) { rcWindow.Left = left; rcWindow.Right = right; rcWindow.Top = top; rcWindow.Bottom = bottom; _SetCursorPos(0, 0); }

void CConsole::_GetConwinSize(int *sizex, int *sizey) { CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); *sizex = bInfo.dwSize.X; *sizey = bInfo.dwSize.Y; }

void CConsole::_GetWindowSize(int *sizex, int *sizey) { *sizex = rcWindow.Right - rcWindow.Left + 1; *sizey = rcWindow.Bottom - rcWindow.Top + 1; }

void CConsole::_SetCursorPos(int x, int y) { COORD pos = {rcWindow.Left+x, rcWindow.Top+y}; if (pos.X>rcWindow.Right) return; if (pos.Y>rcWindow.Bottom) return; SetConsoleCursorPosition(hOut, pos); }

void CConsole::_GetCursorPos(int *x, int *y) { CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); COORD pos = bInfo.dwCursorPosition; *x = pos.X - rcWindow.Left; *y = pos.Y - rcWindow.Top; }

void CConsole::_SetBackColor(int color) { bkColorIndex = color; SetConsoleTextAttribute(hOut, bkColor[bkColorIndex]|foColor[foColorIndex]); }

int CConsole::_GetBackColor(void) { return bkColorIndex; }

void CConsole::_SetForeColor(int color) { foColorIndex = color; SetConsoleTextAttribute(hOut, bkColor[bkColorIndex]|foColor[foColorIndex]); }

int CConsole::_GetForeColor(void) { return foColorIndex; }

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_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; ichar 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; ichPos[nNum] = i+1; nNum++; } }

chPos[nNum] = i;

// 计算最长行的字符长度 int nSize = 0;

for (i=0; inSize = max(nSize, (int)strlen(caption)+2); _SaveSettings(); // 计算窗口

int x1, y1, x2, y2; x1 = 0; y1 = 0;

x2 = x1 + nSize + 2; y2 = y1 + nNum + 3;

// 保存以前的设置

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

_DefineWindow(x1, y1, x2+1, y2+1); // 重新定义窗口 _SaveWindow();

_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); // 重新定义窗口 int nColor[3];

bool bShow = true;

switch (mode) { case 1: nColor[0] = 2; nColor[1] = 15; nColor[2] = 15; bShow = false; break; case 2: nColor[0] = 3; nColor[1] = 14; nColor[2] = 14; break; case 3:

nColor[0] = 4; nColor[1] = 14; nColor[2] = 14; break; default: nColor[0] = m_nFrameColor[0]; nColor[1] = m_nFrameColor[1]; nColor[2] = m_nControlColor[1]; bShow = false; break; } _SetBackColor(nColor[0]); _SetForeColor(nColor[1]); _ShowCursor(bShow); _ClearWindow(); _DrawBox(0, 0, x2-x1+1, y2-y1+1, 1); _SetForeColor(nColor[2]); // 输出标题 _OutTextXY((nSize - strlen(caption))/2 + 2, 0, caption); unsigned int nStart, nDispNum; for (i=0; ichar* CConUI::_InputBox(char *name, int x, int y, int nchars, bool center) { _SaveSettings(); // 保存以前的设置 if (nchars<(int)strlen(name)) nchars = (int)strlen(name); // 计算窗口 int x1, y1, x2, y2; x1 = x;

y1 = y; x2 = x1 + nchars + 2; y2 = y1 + 2; if (center) _CalCenterWindow(&x1, &y1, &x2, &y2); _DefineWindow(x1, y1, x2+1, y2+1); // 重新定义窗口 _SaveWindow(); _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]); _ShowCursor(true); _ClearWindow(); _DrawBox(0, 0, x2-x1+1, y2-y1+1); // 绘制提示文本 _OutTextXY((nchars - strlen(name))/2 + 2, 0, name, strlen(name)); _LoadSettings(); int res, num=0; char strRes[256]; //m_nCharNum = 0; res = _InputLine(x1+1, y1+1, nchars, m_nControlColor[0], m_nControlColor[1], strRes, &num); _PutWindow(x1, y1); if (res == 0) { strncpy(m_InputChars, strRes, num); return m_InputChars; } else return \"\"; }

int CConUI::_InputLine(int x, int y, int nlength, int bkcolor, int focolor, char *str, int *nchars)

{

_SaveSettings(); // 保存以前的设置

// 计算窗口

int x1, y1, x2, y2; x1 = x; y1 = y;

x2 = x1 + nlength - 1; y2 = y1;

_DefineWindow(x1, y1, x2, y2); // 重新定义窗口 // 绘制输入框

_SetBackColor(bkcolor); _SetForeColor(focolor); _ClearWindow();

int nInputCharNum = 0;

int nCharPos = 0; // 字符位置 int nCursorPos; // 光标位置,范围从0到nchars-1 int nLeft = 0; // 滚动的字符个数 unsigned int ch; int i;

if (m_nCharNum>0) { _OutTextXY(0, 0, &m_InputChars[0], min(m_nCharNum, nlength)); nInputCharNum = m_nCharNum; }

_ShowCursor(true); _SetCursorPos(0, 0);

// 控制键盘输入,当按ENTER键或ESC键结束输入 // 按ESC键后,返回NULL for(;;) { bool bChanged = false; ch = _GetKeyChar(); // 当按下ESC、ENETR和TAB键退出 if ((ch == VK_ESCAPE)||(ch == VK_RETURN)||(ch == VK_TAB)) break; if ((ch == VK_UP)||(ch == VK_DOWN)) break; switch (ch) { case VK_HOME: // HOME键

}

nCharPos = 0; nLeft = 0; bChanged = true; break; case VK_END: // END键 nCharPos = nInputCharNum; bChanged = true; nLeft = nCharPos - nlength; if (nLeft<0) nLeft = 0; break;

case VK_LEFT: // 向左 nCharPos--; if (nCharPos<0) nCharPos = 0; else bChanged = true; break;

case VK_RIGHT: // 向右 nCharPos++; if (nCharPos>nInputCharNum) nCharPos = nInputCharNum; else bChanged = true; break;

case VK_BACK: // Back Space nCharPos--; if (nCharPos<0) { nCharPos = 0; break; }

case VK_DELETE: // DEL键,删除当前字符 for (i=nCharPos+1; i<=nInputCharNum; i++) { m_InputChars[i-1] = m_InputChars[i]; bChanged = true; } if (bChanged){ nInputCharNum--; if (nInputCharNum<0) { nInputCharNum = 0; bChanged = false; } } break;

}

// 显示和记录字符以及相应的光标

if (isprint(HIBYTE(ch))) { // 判断是否是有效字符 for (i = nInputCharNum; i>nCharPos; i--) m_InputChars[i] = m_InputChars[i-1]; m_InputChars[nCharPos] = HIBYTE(ch); nCharPos++; nInputCharNum++; if (nInputCharNum >= 252) nInputCharNum = 252; if (nCharPos >= 252) nCharPos = 252; }

bChanged = true;

if ((nCharPos - nLeft)>=nlength) nLeft++; int nCmp = 0;

if (ch == VK_BACK) nCmp = 1; if ((nCharPos - nLeft)< nCmp) { nLeft--; if (nLeft<0) nLeft = 0; }

if (nLeft>0) bChanged = true;

if (bChanged) { _ClearWindow(); int nNum = min(nlength-1, nInputCharNum); // 可以显示的字符 if ((nCharPos=nlength)) nNum++; }

_OutTextXY(0, 0, &m_InputChars[nLeft], nNum); bChanged = false;

nCursorPos = nCharPos - nLeft; _SetCursorPos(nCursorPos, 0);

_LoadSettings();

*nchars = nInputCharNum;

m_nCharNum = nInputCharNum; if (m_nCharNum>0) { strncpy(str, m_InputChars, nInputCharNum); }

else str = NULL; if (ch == VK_ESCAPE) return -1; if (ch == VK_RETURN) return 0; if (ch == VK_TAB) return 1; if (ch == VK_UP) return 2; if (ch == VK_DOWN) return 3; return -1; }

int CConUI::_GetOptions(char **str, int x, int y, int num, int *chpos, bool center) { // 计算最长选项文本的字符个数 unsigned int nNameSize = 10, nTitleCharNum; nTitleCharNum = strlen(m_strOptionsTitle); if (nNameSize_SetForeColor(m_nFrameColor[1]); _ClearWindow();

_DrawBox(0, 0, x2-x1+1, y2-y1+1);

// 输出标题

_OutTextXY((nNameSize - nTitleCharNum)/2 + 2, 0, m_strOptionsTitle);

int posX = 2, posY = 1, n;

// 绘制并解析菜单 m_nMenuItemNum = 0; for (i=0; iif (chpos) n = chpos[i]; else n = 0;

char chItem = (char)toupper(str[i][n]); _SetForeColor(m_nMenuColor[2]);

_OutTextXY(posX + n, posY, &chItem, 1);

menuItem[m_nMenuItemNum].chPos = n; menuItem[m_nMenuItemNum].chItem = chItem; menuItem[m_nMenuItemNum].itemPos = posY; strcpy(menuItem[m_nMenuItemNum].itemName, str[i]); m_nMenuItemNum++; }

posY++;

// 控制键盘输入,当按ENTER键或ESC键或有效的字符结束输入 // 按ESC键后,返回-1 static int nSelectItemNext = 0;

if (nSelectItemNext<0) nSelectItemNext = 0;

if (nSelectItemNext>(m_nMenuItemNum-1)) nSelectItemNext = 0; int nSelectItem = nSelectItemNext, ch, nBak = nSelectItem; bool bOK = false;

// 绘制选择的文本

_SetBackColor(m_nMenuColor[0]); _SetForeColor(m_nMenuColor[1]); posY = menuItem[nSelectItem].itemPos;

_FillBox(posX - 1, posY, nNameSize+2, 1, false);

for(;;) { bool bChanged = false; ch = _GetKeyChar(); // 当按下ESC、ENETR和TAB键退出 if ((ch == VK_ESCAPE)||(ch == VK_RETURN)) break; if ((ch == VK_LEFT)||(ch == VK_RIGHT)) break;

char c = HIBYTE(ch);

if (isprint(c)) { // 判断是否是有效字符 c = (char)toupper(c); for (int i=0; iswitch (ch) { case VK_UP: // 向上 nSelectItem--; if (nSelectItem<0) nSelectItem = m_nMenuItemNum - 1; bChanged = true; break; case VK_DOWN: // 向下 nSelectItem++; if (nSelectItem>(m_nMenuItemNum-1))

nSelectItem = 0; bChanged = true; break; } if (bChanged){ bChanged = false; // 恢复原来的文本 _SetBackColor(m_nFrameColor[0]); _SetForeColor(m_nControlColor[1]); posY = menuItem[nBak].itemPos; _FillBox(posX - 1, posY, nNameSize+2, 1, false); _SetForeColor(m_nMenuColor[2]); char chItem = menuItem[nBak].chItem; _OutTextXY(posX + menuItem[nBak].chPos, posY, &chItem, 1); // 绘制选择的文本 nBak = nSelectItem; posY = menuItem[nBak].itemPos; _SetBackColor(m_nMenuColor[0]); _SetForeColor(m_nMenuColor[1]); _FillBox(posX - 1, posY, nNameSize+2, 1, false); } } _PutWindow(x1, y1); _LoadSettings(); nSelectItemNext = nSelectItem; if (ch == VK_RETURN) bOK = true; if (bOK) { return nSelectItem; } else return -1; }

void CConUI::_CalCenterWindow(int *x1, int *y1, int *x2, int *y2) {

int nSizeX, nSizeY; _GetConwinSize(&nSizeX, &nSizeY); int w = (*x2 - *x1); int h = (*y2 - *y1); *x1 = (nSizeX - w)/2; *y1 = (nSizeY - h)/2; *x2 = *x1 + w; *y2 = *y1 + h; }

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #include

class CGraph : public CObject {

public: CGraph::CGraph(); CGraph::CGraph(CRect rcDraw); CGraph::CGraph(CRect rcDraw, int nMode); void SetDrawRect(CRect rcDraw); void SetDrawMode(int nMode); void AddData(unsigned int data); // 添加数据 void Draw(CDC *pDC, bool isDispData = FALSE); // 绘制,当isDispData务TRUE,在直方图的顶上显示数字或饼图中显示百分比 private: CRect m_rectDraw; // 用于绘制直方图和饼图的整个范围 int m_nMode; // 0表示直方图,其它值表示饼图 CUIntArray m_uDataArray; // 用于存放各个分量的值 LOGFONT m_lfData; void DrawBar(CDC *pDC, bool isDispData); void DrawPie(CDC *pDC); void InitGraph(CRect rcDraw, int nMode); };

CGraph::CGraph() { CRect rc(0, 0, 100, 100); InitGraph(rc, 0); }

CGraph::CGraph(CRect rcDraw) {

InitGraph(rcDraw, 0); }

CGraph::CGraph(CRect rcDraw, int nMode) { InitGraph(rcDraw, nMode); }

void CGraph::InitGraph(CRect rcDraw, int nMode) { SetDrawRect(rcDraw); SetDrawMode(nMode); memset(&m_lfData, 0, sizeof(LOGFONT)); m_lfData.lfHeight = -13; m_lfData.lfCharSet = GB2312_CHARSET; strcpy((LPSTR)&(m_lfData.lfFaceName), \"宋体\"); }

void CGraph::SetDrawRect(CRect rcDraw) { m_rectDraw = rcDraw; }

void CGraph::SetDrawMode(int nMode) { m_nMode = nMode; }

void CGraph::AddData(unsigned int data) // 添加数据 { m_uDataArray.Add(data); }

void CGraph::Draw(CDC *pDC, bool isDispData) { // 绘制背景区域 pDC->FillSolidRect( m_rectDraw, RGB(255,255,255)); pDC->Draw3dRect( m_rectDraw, RGB( 96, 96, 96 ), RGB( 255, 255, 255 ) ); m_rectDraw.InflateRect( -10, -10 ); if (m_nMode) DrawPie(pDC); else DrawBar(pDC, isDispData); }

void CGraph::DrawBar(CDC *pDC, bool isDispData) { // 计算最大的量

UINT nData, nDataNum, nDataMax = 0; nDataNum = m_uDataArray.GetSize(); if (nDataNum < 1) return; for (UINT i=0; iSelectObject(&cf); for (i=0; iSelectObject(&brush); pDC->Rectangle(rcDraw); pDC->SelectObject(oldBrush); if (isDispData) { CRect rcData = rcDraw; rcData.bottom = rcData.top; rcData.top -= 20; CString str; str.Format(\"%d\ pDC->DrawText(str, rcData, DT_VCENTER | DT_CENTER | DT_SINGLELINE ); } nIndex++; if (nIndex >= 6) nIndex = 0;

rcDraw.left = rcDraw.right; } pDC->SelectObject(oldfont); // 恢复设备环境原来的属性 }

void CGraph::DrawPie(CDC *pDC) { // 计算最大的量 UINT nData, nDataNum, nDataSum = 0; nDataNum = m_uDataArray.GetSize(); if (nDataNum < 1) return; for (UINT i=0; i 0) rcDraw.DeflateRect(nDelta/2, 0); else rcDraw.DeflateRect(0, -nDelta/2); double dbPer = (double)(3.14159 * 2.0) / (double)nDataSum; // 每度相当于多少数值 UINT nColor[] = {RGB(0,0,0), RGB(64, 64, 64), RGB(128, 128, 128), RGB(160, 160, 160), RGB(192, 192, 192), RGB(224, 224, 224)}; int nIndex = 0, x, y; CPoint pt1 = rcDraw.CenterPoint(), pt2; pt1.x = rcDraw.right; CFont cf; cf.CreateFontIndirect(&m_lfData); CFont* oldfont = pDC->SelectObject(&cf); double dbDegree = 0; for (i=0; iCBrush brush(nColor[nIndex]);

CBrush* oldBrush = pDC->SelectObject(&brush); pDC->Pie(rcDraw, pt2, pt1); pDC->SelectObject(oldBrush); nIndex++;

if (nIndex >= 6) nIndex = 0; pt1 = pt2;

}

pDC->SelectObject(oldfont); }

// 恢复设备环境原来的属性

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务