Разработка полноценных Windows-приложений
4. Вывод результатов и их сохранение
Описание вывода результатов частично затронуто в предыдущем пункте. Теперь рассмотрим вывод форматированного текста в файл. Для этого создадим пункт меню File Save as…, и обработаем нажатие на него. Но прежде добавим в файл ChildView.h строку:
protected: static DWORD CALLBACK FileStreamOutCallback(DWORD dwCookie, LPBYTE pbBuf, LONG cb, LONG *pcb); //Функция обратного вызова для записи данных в файл
и определим объявленный метод в файле ChildView.cpp:
DWORD CALLBACK CChildView::FileStreamOutCallback(DWORD dwCookie, LPBYTE pbBuf, LONG cb, LONG *pcb) { CFile *pFile = (CFile*) dwCookie; pFile->Write(pbBuf,cb); *pcb = cb; return 0; }
Обработчик пункта меню File Save as…
void CChildView::OnFileSaveas() { CString strFilter; //Строка для поддерживаемых форматов данных CString strFileName; //Строка для имени файла CString strExtension; //Строка для расширения файла strFilter = "Text file|*.txt|Rich text format file|*.rtf||"; //Инициализация строки поддерживаемыми форматами CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER,strFilter); //Создание диалога сохранения if(dlg.DoModal() == IDOK) //Если нажата кнопка Ok { strFileName = dlg.m_ofn.lpstrFile; //Инициализируем строку с именем файла if (dlg.m_ofn.nFileExtension == 0) //Если пользователь не ввел расширение { switch (dlg.m_ofn.nFilterIndex) //В зависисмости от выбранного формата { case 1: strExtension = "txt"; break; //Инициализируем строку case 2: strExtension = "rtf"; break; //с расширением default: break; } strFileName = strFileName + '.' + strExtension; //Окончательно записываем путь имя и расширение файла } EDITSTREAM es; //Создаем структуру потока CFile OutFile(strFileName,CFile::modeCreate|CFile::modeWrite); //Открываем файл для записи es.dwCookie = (DWORD) &OutFile; //Определяем поле структуры, указывающее куда записывать данные es.pfnCallback = FileStreamOutCallback; //Задаем функцию записи switch(dlg.m_ofn.nFilterIndex) //В зависимости от выбранного формата { case 1: m_Rich.StreamOut(SF_TEXT,es); break; //Записываем данные case 2: m_Rich.StreamOut(SF_RTF,es); break; //в файл default: break; } } }
Процедура записи данных в файл похожа на процедуру чтения. Мы пользуемся методом StreamOut(int nFormat, EDITSTREAM &es) класса CRichEditCtrl, который требует аргументами формат записываемых данных и структуру потока. Структура потока EDITSTREAM определяется заданием пункта назначения и функции записи. Добавим строку:
#include <algorithm>
в конец файла stdafx.h. Скомпилируем и запустим приложение. В результате, в соответствии с открытым текстовым документом, получается следующее: рис. 5.6 рис. 5.7 рис. 5.8
Приложение "Метод наименьших квадратов "
В данном параграфе, на примере создания приложения "Метод наименьших квадратов (МНК) ", рассматриваются следующие вопросы: диалог в качестве основного окна приложения, элемент управления CListCtrl, элемент управления CRichEditCtrl, класс CArray, работа с матрицами.
Постановка задачи. Теоретический материал
Пусть у нас есть следующая таблица:
Требуется построить полином y=f(x) заданной степени k: k меньше n-1 такой, что сумма квадратов расстояний от точек таблицы до графика полинома была наименьшей. Для поиска коэффициентов полинома составим следующий функционал:
и поставим задачу минимизации этого функционала F -> min. Полином запишем в виде
тогда необходимое условие минимума запишется в виде:
Данная система имеет единственное решение, если k<n-1. Значит, существует единственный полином доставляющий минимум этому функционалу, с коэффициентами представимыми решением указанной системы. Напишем программу для нахождения коэффициентов полинома.