#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 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::Update(int nRec, CStudentRec stu) { fstream file(strFileName, ios::in|ios::out|ios::binary); // 二进制读写方式 if (!file) { cout<<\"the \"< int CStudentFile::GetRecCount(void) { fstream file(strFileName, ios::in|ios::nocreate); // 打开文件用于只读 if (!file) { cout<<\"the \"< int CStudentFile::GetStuRec( CStudentRec* data) { fstream file(strFileName, ios::in|ios::nocreate); // 打开文件用于只读 if (!file) { cout<<\"the \"< \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ // 文件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< 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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /* 用于控制台窗口界面设计,版本1.0 2002 - 2003 2006.5 (1) 添加了控制台窗口的字体设计, (2) 添加了边框型式, (3) 添加主框架窗口的界面 */ #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; i 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.X 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 _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 chPos[nNum] = i; // 计算最长行的字符长度 int nSize = 0; for (i=0; i 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; i 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 _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 _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; i 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; i 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; i 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 CBrush* oldBrush = pDC->SelectObject(&brush); pDC->Pie(rcDraw, pt2, pt1); pDC->SelectObject(oldBrush); nIndex++; if (nIndex >= 6) nIndex = 0; pt1 = pt2; } pDC->SelectObject(oldfont); } // 恢复设备环境原来的属性 因篇幅问题不能全部显示,请点此查看更多更全内容