imho.ws |
![]() |
![]() |
![]() |
# 1 |
Guest
Сообщения: n/a
|
Построение диаграммы
Есть программа написанная на Visual Studio 2005 (win 32 project). Вот задание:
Программа читает текстовый файл с числовыми данными в виде одномерного массива: 1. Вычисляет параметры «Описательной статистики» в соответствии с MS Excel. 2. Выводит данные в окне. 3. В отдельном окне выводит частотную диаграмму в виде столбиковой диаграммы, опять же в соответствии с MS Excel. Программа работает но сделана неочень правильно. Как можно её максимально упростить но чтоб не потерялась функциональность листинг формы #include "stdafx.h" #include "file.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK WndGraph(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_FILE, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FILE)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FILE)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FILE); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // #include <commdlg.h> #include <vector> #include <string> #include <fstream> #include <commctrl.h> //кнопки #include <math.h> //математические функции using namespace std; //окно диаграмм static WNDCLASSEX wcgraph; static HWND hGraph; //описание кнопок TBBUTTON tbb[] ={ {STD_FILENEW, ID_FILE_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0}, {STD_FILEOPEN, ID_FILE_OPEN,TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0}, {STD_FILESAVE, ID_FILE_SAVE,TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0} }; HWND hwndToolBar; //дескриптор панели инструментов static vector<string> v; vector<string>::iterator it; static vector<double> val; vector<double>::iterator it_val; static double maximum, minimum; //чтение и запись данных в вектор int ReadData() { double vl; //чтение файла for(it = v.begin(); it != v.end(); ++it) { if(sscanf(it->c_str(),"%lf", &vl) != 1) vl = 0.0; val.push_back(vl); } it_val = val.begin(); minimum = maximum = *it_val; //поиск max и min for(++it_val; it_val != val.end(); ++it_val) { if(maximum < *it_val) maximum = *it_val; else if (minimum > *it_val) minimum = *it_val; } return 0; } //расчет моды и медианы int Mediana_Moda(double &median, double &moda) { int i, j, n, count, temp; double z, *num; n = v.size(); num = new double[n]; //сортировка for(it_val = val.begin(), i = 0; it_val != val.end(); ++it_val, i++) num[i] = *it_val; for (i = 0; i < n-1; i++) for (j = n-1; j > i; j--) if (num[j] < num[j-1]) z = num[j], num[j] = num[j-1], num[j-1] = z; //определение медианы if(n%2) median = num[n/2]; else median = (num[n/2] + num[n/2-1])/2; //определение моды count = temp = 0; for(i = 0; i < n; i++) { count = 0; for(j = 0; j < n; j++) if(num[i] == num[j]) count++; if(count > temp) { moda = num[i]; temp = count; } if(temp == 1) moda = NULL; } return 0; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static TCHAR name[256]; static OPENFILENAME file; ifstream in; ofstream out; static int n, sx, cxClient, cyClient, iVscrollPos, iHscrollPos, NUMLINES, MAX_STRING; char ch, Buf[256], buf[15]; static SIZE size; string st; int i, k; static int size_Toolbar; RECT rt; static LOGFONT lf; static CHOOSEFONT cf; static HFONT hfont; TEXTMETRIC tm; char texts[128]; double disp_vib, stand_otkl, sredn, summa, mediana, moda, exscess, assim, interval, stand_osh; //результаты вычислений switch (message) { case WM_CREATE: file.lStructSize = sizeof(OPENFILENAME); file.hwndOwner = NULL; file.hInstance = hInst; file.lpstrFilter = _T("Text *.txt\0 *.txt"); file.lpstrCustomFilter = NULL; file.nMaxCustFilter = 0; file.nFilterIndex = 0; file.lpstrFile = name; file.nMaxFile = 256; file.lpstrFileTitle = NULL; file.nMaxFileTitle = 0; file.lpstrInitialDir = _T(".\\"); file.nFileOffset = 0; file.nFileExtension = 0; file.lpstrDefExt = _T("txt"); file.lCustData = 0; file.lpfnHook =NULL; file.lpTemplateName = NULL; hdc = GetDC(hWnd); GetTextExtentPoint32(hdc,_T("0"),1,&size); ReleaseDC(hWnd, hdc); //создание панели инструментов hwndToolBar = CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | CCS_TOP,1, 0,HINST_COMMCTRL,IDB_STD_SMALL_COLOR, tbb,3,0,0,0,0,sizeof(TBBUTTON)); //шрифт cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; cf.hwndOwner = hWnd; cf.lpLogFont = &lf; cf.lStructSize = sizeof(CHOOSEFONT); break; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); k = n - cyClient/size.cy; if (k > 0) NUMLINES = k; else NUMLINES = iVscrollPos = 0; SetScrollRange(hWnd, SB_VERT, 0, NUMLINES, FALSE); SetScrollPos (hWnd, SB_VERT, iVscrollPos, TRUE); k = n - (cyClient - size_Toolbar)/size.cy; if (k > 0) MAX_STRING = k; else MAX_STRING = iHscrollPos = 0; SetScrollRange(hWnd, SB_HORZ, 0, MAX_STRING, FALSE); SetScrollPos(hWnd, SB_HORZ, iHscrollPos, TRUE); //изменение размеров панели инструментов SendMessage(hwndToolBar, TB_AUTOSIZE, 0, 0); //высота панели инструментов GetWindowRect(hwndToolBar,&rt); size_Toolbar = rt.bottom - rt.top; break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_FILE_NEW : if (!v.empty()) vector<string>().swap(v); if (!val.empty()) vector<double>().swap(val); n = sx = 0; SendMessage(hWnd, WM_SIZE, 0, cyClient<<16 | cxClient); InvalidateRect(hWnd,NULL,1); break; case ID_FILE_OPEN : //если файл уже открыт, то появляется предупреждение if(!v.empty()) { MessageBox(hWnd, _T("Файл уже открыт!"), _T("Ошибк"), MB_OK | MB_ICONERROR); break; } file.lpstrTitle = _T("Открыть файл для чтения"); file.Flags = OFN_HIDEREADONLY; if (!GetOpenFileName(&file)) return 1; in.open(name); while (getline(in,st)) { if (sx < st.length()) sx = st.length(); v.push_back(st); } in.close(); n = v.size(); SendMessage(hWnd, WM_SIZE, 0, cyClient<<16 | cxClient); InvalidateRect(hWnd,NULL,1); break; case ID_FILE_SAVE : file.lpstrTitle = _T("Открыть файл для записи"); file.Flags = OFN_NOTESTFILECREATE; if (!GetSaveFileName(&file)) return 1; out.open(name); for (it = v.begin(); it != v.end(); ++it) out << *it << endl; out.close(); break; case ID_FILE_FONT: if(ChooseFont(&cf)) { if (hfont) DeleteObject(hfont); hfont = CreateFontIndirect(&lf); hdc = GetDC(hWnd); SelectObject(hdc,hfont); GetTextMetrics(hdc,&tm); size.cx = tm.tmAveCharWidth; size.cy = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hWnd, hdc); SendMessage(hWnd, WM_SIZE,0,cyClient<<16 | cxClient); InvalidateRect(hWnd,NULL,1); } break; case ID_GRAFIK: if (IsWindow(hGraph)) break; if (!v.size()) { //если значения не заданы то появляется сообщение с ошибкой MessageBox(hWnd, _T("Данныен не введены!"), _T("Ошибка"), MB_OK | MB_ICONERROR); break; } wcgraph.cbSize = sizeof(WNDCLASSEX); wcgraph.style = CS_HREDRAW | CS_VREDRAW; wcgraph.lpfnWndProc = (WNDPROC)WndGraph; wcgraph.hInstance = hInst; wcgraph.hCursor = LoadCursor(NULL, IDC_CROSS); wcgraph.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); wcgraph.lpszClassName = _T("ChildClass"); RegisterClassEx(&wcgraph); hGraph = CreateWindow(_T("ChildClass"), _T("Grafik"), WS_SYSMENU | WS_CHILD|WS_VISIBLE|WS_THICKFRAME|WS_CAPTION|WS_EX_NOPARENTNOTIFY, cxClient/4,cyClient/4,cxClient/2,cyClient/2,hWnd,0, hInst, NULL); break; case ID_STATISTIC: //анализ данных, вывод статистики if(!v.size()) { MessageBox(hWnd, _T("Данные не введены!"), _T("Ошбка"), MB_OK | MB_ICONERROR); break; } hdc = GetDC(hWnd); if(val.empty())ReadData(); //сумма и среднее значение for(summa = 0, i = 0, it_val = val.begin(); it_val != val.end(); ++it_val, i++) summa += *it_val; sredn = summa/i; //медиана и мода Mediana_Moda(mediana, moda); //дисперсия for(disp_vib = 0, it_val = val.begin(); it_val != val.end(); ++it_val) disp_vib += (*it_val - sredn) * (*it_val - sredn) / (i-1); //стандартное отклонение stand_otkl = sqrt(disp_vib); //интервал interval = maximum - minimum; //стандартная ошибка stand_osh = stand_otkl / sqrt((double)i); //асимметричность for(assim = 0, it_val = val.begin(); it_val != val.end(); ++it_val) assim += (*it_val - sredn) * (*it_val - sredn) * (*it_val - sredn) / (disp_vib * stand_otkl) * i/((i-1)*(i-2)); //эксцесс for(exscess = 0, it_val = val.begin(); it_val != val.end(); ++it_val) exscess += (*it_val - sredn) * (*it_val - sredn) * (*it_val - sredn) * (*it_val - sredn) / (disp_vib * disp_vib); exscess = exscess * (i*(i+1)) / ((i-1)*(i-2)*(i-3)) - 3.0*(i-1)*(i-1) / ((i-2)*(i-3)); //вывод результатов GetTextMetrics(hdc,&tm); SetTextAlign(hdc, TA_TOP | TA_RIGHT); sprintf(buf, "%6.2lf", sredn); strcpy(texts, "Среднее: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*1, texts, strlen(texts)); sprintf(buf, "%6.2lf", stand_osh); strcpy(texts, "Стандартная ошибка: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*2, texts, strlen(texts)); sprintf(buf, "%6.2lf", mediana); strcpy(texts, "Медиана: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*3, texts, strlen(texts)); sprintf(buf, "%6.2lf", moda); strcpy(texts, "Мода: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*4, texts, strlen(texts)); sprintf(buf, "%6.2lf", stand_otkl); strcpy(texts, "Стандартное отклонение: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*5, texts, strlen(texts)); sprintf(buf, "%6.2lf", disp_vib); strcpy(texts, "Дисперсия выборки: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*6, texts, strlen(texts)); sprintf(buf, "%6.2lf", exscess); strcpy(texts, "Эксцесс: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*7, texts, strlen(texts)); sprintf(buf, "%6.2lf", assim); strcpy(texts, "Асимметричность: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*8, texts, strlen(texts)); sprintf(buf, "%6.2lf", interval); strcpy(texts, "Интервал: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*9, texts, strlen(texts)); sprintf(buf, "%6.1lf", minimum); strcpy(texts, "Минимум: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*10, texts, strlen(texts)); sprintf(buf, "%6.1lf", maximum); strcpy(texts, "Максимум: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*11, texts, strlen(texts)); sprintf(buf, "%6.2lf", summa); strcpy(texts, "Сумма: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*12, texts, strlen(texts)); sprintf(buf, "%6.2lf", (double)i); strcpy(texts, "Счет: "); strcat(texts, buf); TextOutA(hdc, cxClient-10, size_Toolbar+tm.tmHeight*13, texts, strlen(texts)); ReleaseDC(hWnd, hdc); break; case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_VSCROLL : switch(LOWORD(wParam)) { case SB_LINEUP : iVscrollPos--; break; case SB_LINEDOWN : iVscrollPos++; break; case SB_PAGEUP : iVscrollPos -= cyClient / size.cy; break; case SB_PAGEDOWN : iVscrollPos += cyClient / size.cy; break; case SB_THUMBPOSITION : iVscrollPos = HIWORD(wParam); break; } iVscrollPos = max(0, min(iVscrollPos, NUMLINES)); if (iVscrollPos != GetScrollPos(hWnd, SB_VERT)) { SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE); InvalidateRect(hWnd, NULL, TRUE); } break; case WM_HSCROLL : switch(LOWORD(wParam)) { case SB_LINEUP : iHscrollPos--; break; case SB_LINEDOWN : iHscrollPos++; break; case SB_PAGEUP : iHscrollPos -= 8; break; case SB_PAGEDOWN : iHscrollPos += 8; break; case SB_THUMBPOSITION : iHscrollPos = HIWORD(wParam); break; } iHscrollPos = max(0, min(iHscrollPos, MAX_STRING)); if (iHscrollPos != GetScrollPos(hWnd, SB_HORZ)) { SetScrollPos(hWnd, SB_HORZ, iHscrollPos, TRUE); InvalidateRect(hWnd, NULL, TRUE); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); if (hfont) { SelectObject(hdc,hfont); SetTextColor(hdc,cf.rgbColors); } for (i = size_Toolbar, it = v.begin() + iVscrollPos; it < v.end() && i < cyClient; ++it, i += size.cy) { if (iHscrollPos < it->length()) { for (k = iHscrollPos; k < it->length(); k++ ) Buf[k] = ((ch =it->at(k)) == _T('\t'))? _T(' ') : ch; TextOutA(hdc, 0, i, Buf+iHscrollPos, k-iHscrollPos); } } EndPaint(hWnd, &ps); break; case WM_DESTROY: DeleteObject(hfont); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } LRESULT CALLBACK WndGraph(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static HBRUSH hbrush1; static HPEN hpen1; HPEN hpen_def; HBRUSH brush_def; char s[10]; static int cxClient, cyClient, size; static double *num; int i; double vl; const int indent = 30; HFONT new_font, old_font; switch (message) { case WM_CREATE: size = v.size(); num = new double[size]; //массив для логических данных hbrush1 = CreateSolidBrush(RGB(243, 57, 14)); //цветная кисть, для закрашивания диаграммы hpen1 = CreatePen(PS_SOLID, 2, RGB(0,0,0)); //жирное перо if(val.empty())ReadData(); break; case WM_SIZE: cxClient = LOWORD(lParam); //ширина окна cyClient = HIWORD(lParam); //высота окна vl = maximum - minimum; //преобразование данных for(i = 0, it_val = val.begin(); it_val != val.end(); ++it_val, i++) num[i] = cyClient - indent - (*it_val - minimum)/vl * (cyClient - indent*2); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); //шрифт для подписи столбиков new_font = CreateFontA(15,0,0,0,700,1,0,0, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE,"Times New Roman"); //системный шрифт запоминаем old_font = (HFONT)SelectObject(hdc, new_font); //шрифт hpen_def = (HPEN)SelectObject(hdc, hpen1); //перо в 2px толщиной для осей brush_def = (HBRUSH)SelectObject(hdc, hbrush1); //цветная кисть для столбиков MoveToEx(hdc, indent, indent, NULL); LineTo(hdc, indent, cyClient-indent); //ось Y LineTo(hdc, cxClient-indent, cyClient-indent); //ось X SelectObject(hdc, hpen_def); //перо по умолчанию SetTextAlign(hdc, TA_BOTTOM | TA_LEFT); //вырвнивание текста //первый столбик диаграммы с подписью Rectangle(hdc, indent*(1), num[0], indent*(2), cyClient-indent); it_val = val.begin(); sprintf(s, "%6.1lf", *it_val); TextOutA(hdc, indent+3, num[0]-2, s, 6); //построение диаграммы с подписями столбиков for(i = 1, ++it_val; i < size, it_val != val.end(); i++, ++it_val) { sprintf(s, "%6.1lf", *it_val); TextOutA(hdc, indent*(i+1)+i+3, num[i]-2, s, 6); Rectangle(hdc, indent*(i+1)+i, num[i], indent*(i+2)+i, cyClient-indent); } SelectObject(hdc, brush_def); //установка системной кисти SelectObject(hdc, old_font); //установка системного шрифта DeleteObject(new_font); //удаление шрифта EndPaint(hWnd, &ps); break; case WM_DESTROY: DeleteObject(hbrush1); //удаление кисти DeleteObject(hpen1); //удаление шрифта break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } |