Казахстан |
Разработка полноценных Windows-приложений
Проектирование и разработка приложений
Этапы разработки
- Создать ресурс диалогового окна.
- Организовать ввод и редактирование начальных данных.
- Построить СЛАУ и решить ее.
- Организовать вывод результатов.
Создадим с помощью мастера MFC приложение "Regr" на основе диалогового окна. Для этого установим Application type в значение Dialog based. Снимем флажок Use Unicode libraries.
1. Создание ресурса диалогового окна
Создадим диалоговое окно с тремя текстовыми полями для ввода данных в таблицу и указания степени аппроксимации, четырьмя кнопками(Add, Delete, Start Approximation, Exit), списковым представлением для отображения таблицы точек и текстовым полем RichEdit для вывода строки результата. Шаблон диалога приведен на рисунке: рис. 5.9
Для всех элементов управления типа поле ввода, установим свойство Right Align Text в значение true. Для элемента управления типа поле ввода, расположенного напротив надписи Approximation degree: установим свойство Number в значение true. Для элемента управления типа поле ввода с форматированием, установим свойство Auto HScroll в значение true, свойство Align Text в значение center, свойство Horizontal Scroll в значение true, свойство Read Only в значение true. Для элемента управления типа списковое представление, установим свойство Border в значение false (убираем рамку для того, чтобы проще было получить размеры клиентской области элемента управления), свойство Single Selection в значение true, свойство View в значение Report (будем выводить таблицу).
2. Ввод и редактирование начальных данных
Начальные данные представляют собой точки плоскости. Как и в примере "Интерполяционный полином", введем класс, инкапсулирующий вещественную точку на плоскости. Добавим в файл RegrDlg.h, содержащий прототип класса основного диалога, следующий код:
class SDPoint { public: double x; double y; SDPoint():x(0),y(0){} //Конструктор по умолчанию SDPoint(double a, double b):x(a),y(b){} //Конструктор с параметрами };
после строки
#pragma once
Теперь, создадим в классе диалога массив объектов класса SDPoint, который будет хранить начальные данные. Прототип класса CRegrDlg:
// CRegrDlg dialog class CRegrDlg : public CDialog { // Construction public: CRegrDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data enum { IDD = IDD_REGR_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() //Обработчики событий добавлены с помощью мастера public: afx_msg void OnBnClickedButtonAdd(); afx_msg void OnBnClickedButtonDel(); afx_msg void OnBnClickedButtonStart(); public: matrix<double> mRightPart; //Вектор - правая часть системы matrix<double> mNodeMatrix; //Матрица системы CArray<SDPoint,SDPoint&> mInitArr; //Массив точек //Следующие переменные добавлены с помощью утилиты ClassView и связаны с элементами управления double mX; //Координата X точки связана с первым текстовым полем double mY; //Координата Y связана со вторым текстовым полем int mNum; //Степень аппроксимации связана с третьим текстовым полем CListCtrl mListCtrl; //Переменная для управления списковым представлением };
Жирным шрифтом выделена переменная, которую необходимо добавить в данном пункте. CArray - это шаблонный класс, инкапсулирующий динамические массивы в MFC. В качестве первого аргумента шаблону передается тип хранимых в массиве объектов (в данном случае SDPoint ), вторым аргументом передается тип объектов, использующихся для получения доступа к данным массива, обычно это ссылка на тип, указанный в первом аргументе (в данном случае SDPoint ). Для ввода данных в диалоге была создана кнопка Add и два текстовых поля. Добавим в диалоговый класс связанные с текстовыми полями переменные mX, mY, mNum и mListCtrl с помощью мастера. Прежде чем обрабатывать нажатие на кнопку Add, настроим списковое представление. Добавим следующие строки в функцию OnInitDialog():
BOOL CRegrDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } //Настраиваем Элемент управления "списковое представление" CRect cr; mListCtrl.GetWindowRect(&cr); //Получение размеров окна элемента управления mListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_ONECLICKACTIVATE); //Задаем необходимые стили mListCtrl.InsertColumn(0,_T("X"),LVCFMT_LEFT,(cr.right-cr.left)/2); //Добавляем колонку mListCtrl.InsertColumn(1,_T("Y"),LVCFMT_RIGHT,(cr.right-cr.left)/2); //Добавляем еще одну //Настраиваем самую левую колонку LVCOLUMN lvm; //Структура для хранения информации о колонке lvm.mask = LVCF_FMT; //Инициализация полей структуры lvm.fmt = LVCFMT_RIGHT; mListCtrl.SetColumn(0,&lvm); //Задание необходимого стиля колонки SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon return TRUE; // return TRUE unless you set the focus to a control }
Жирным шрифтом выделен добавленный код. А теперь добавим обработчик кнопки Add и Delete. Обработчик нажатия на кнопку Add:
void CRegrDlg::OnBnClickedButtonAdd() { CString str; UpdateData(true); //Обмен данными for(int i = 0; i < mInitArr.GetSize(); i++) //Перебираем все точки в массиве if(mInitArr[i].x == mX && mInitArr[i].y == mY) return; //Если существует такая же, то выходим mInitArr.Add(SDPoint(mX,mY)); //Проверка сделана, повторов нет, добавляем точку в массив str.Format("%f",mX); //Форматирум строку для вывода в таблицу mListCtrl.InsertItem((int)mInitArr.GetSize()-1,str); //Добавляем строку в таблицу str.Format("%f",mY); //Повторяем для следующей колонки mListCtrl.SetItemText((int)mInitArr.GetSize()-1,1,str); }
Обработчик нажатия на кнопку Delete:
void CRegrDlg::OnBnClickedButtonDel() { int n = mListCtrl.GetSelectionMark(); //Получаем номер выделенной строки списка if(n < 0) return; //Если ничего не выделено,то выходим mInitArr.RemoveAt(n); //Удаляем точку из массива mListCtrl.DeleteItem(n); //Удаляем строку из списка }