- •Лабораторные работы по курсу «Инструментальные средства визуального программирования»
- •1. Программирование односвязного списка
- •1.1.Задание
- •1.2.Описание вариантов заданий
- •2.Перегрузка векторных и матричных операций
- •2.1.Задание
- •2.2.Бесценные методические указания
- •2.3.Некоторые особенности перегрузки операций
- •3.Классная работа
- •3.1.Постановка задачи
- •2.4.Варианты заданий
- •3.2.Задания
- •3.3.Методические наказания к первой части работы
- •3.4.Методические наказания ко второй части работы
- •4.Алгоритмы
- •Задание
- •Варианты классов и их обработки
- •5.Приложение WinForms (cli)
- •5.1.Задание
- •5.2.Бесценные методические предписания
- •Int nRec;//Число записей файла, оно же будет числом элементов массивов
- •6.Графика в WinForms (cli)
- •6.1.Задание
- •6.2.Бесценные методические предписания
- •6.3.Индивидуальные задания
- •7.1.Задание
- •7.2.Бесценные методические наставления
- •8.Квикли файдингуем рутсы
- •8.1.Дармовые методические рекомендации
- •8.2.Задание
- •Варианты индивидуальных заданий
- •9.Приложение, основанное на модальном диалоговом окне
- •9.1.Нудные методические указания Модальные и немодальные диалоговые окна
- •Ресурсы и элементы управления
- •Сценарий создания приложения
- •Разбор приложения
- •Усовершенствование приложения
- •10.Разработка графического редактора
- •Задание.
- •10.1.Проектирование программы
- •10.2.Разработка интерфейса
- •Установка флагов
- •Создание меню и панели инструментов
- •Обработка сообщений о нажатии кнопки мыши
- •10.3.Рисование
- •10.4.Растягивание фигур
- •10.5.Обновление изображения
- •10.6.Сохранение метафайла на диске и его загрузка
- •Список ссылок
- •Работы, выполненные в осеннем семестре 2016/2017 по курсу ооп
3.3.Методические наказания к первой части работы
Шаг 1. Создайте приложение SDI по сценарию, изложенному в начале описания этой работы.
Шаг 2. Создайте обработчик команды меню ФайлОткрыть. Он может выглядеть, например, так:
|
По аналогии с приведенным кодом добавьте в обработчик запрос имени файла CPPFileName с реализацией класса. Переменные HFileName и CPPFileName в соответствии с архитектурой документ-вид опишите в классе документ как имеющие тип CString по аналогии с тем, как вы это делали в работе «Разработка графического редактора».
Дальнейший план действий может быть, например, таким.
Шаг 3. Читаем файлы. Опишем в классе документа два массива строк CString: один для заголовочного файла и второй – для файла реализации методов класса. Можно описать эти массивы как «обычные», с заведомо достаточным числом элементов, например, так:
CString HVec[1024], CPPVec[1024];
Этот подход, как и описание указателей на CString, страдает существенными недостатками, в частности, вставка или удаление элементов массива является трудоемкой процедурой и потребует немалых усилий и времени от программиста.
Рациональнее использовать для этой цели контейнеры vector или list из библиотеки STL:
vector <CString> HVec, CPPVec;
list <CString> HVec, CPPVec;
Вектор удобнее тем, что в нем есть перегруженная операция [] и, следовательно, можно обращаться к любому элементу массива по его индексу. Кроме того, в классе vector имеются функции для вставки и удаления элементов вектора.
Чтобы их использовать, добавьте в заголовочный файл документа директивы
#include <vector>
#include <list>
using namespace std;
Куда поместить код чтения файлов в массивы HVec и CPPVec? Если в обработчик события OnFileOpen, то это плохая идея: нельзя разрабатывать большие по объему кода функции и помещать в них несвойственный их назначению код. Посему лучше создать еще одну команду меню, например, ФайлОбработка и создать обработчик этой команды CGenView::OnProcess(). Далее целесообразно создать в классе вида функции чтения заголовочного файла (ReadHeaderFile()) и файла реализации (ReadCPPFile()) и поместить их вызов в обработчик CGenView::OnProcess(). В этих функциях нужно прочесть содержимое указанных текстовых файлов в массивы.
Когда вы будете передавать вектор или список в качестве параметра функции, не забудьте объявить их ссылками, так как в противном случае функция будет работать с копией такого параметра:
bool CGenView::ReadHeaderFile(vector <CString> &HVec, CString HFName)
Для чтения содержимого файлов можно использовать хорошо знакомый вам класс ifstream и функцию этого класса getline(), позволяющую прочесть запись файла целиком. В качестве параметра этой функции надо использовать тип char *, так как параметр типа CString не подходит:
char Buf[1024];
do
{
MyFile.getline(Buf,sizeof(Buf),'\n');
HVec.push_back(CString(Buf));
...
Шаг 4. Сохранение файлов. Прежде чем вы начнете усовершенствовать определение класса, научитесь корректно сохранять результаты. Для этого просто запишите содержимое массивов (или списков, если вы выбрали их) в файлы. Для этого создайте обработчик команды ФайлСохранить и в нем просто запишите массивы в соответствующие файлы, т.е. в файлы с теми же именами, которые вы открывали. Рекомендую предварительно сделать копии этих файлов (с помощью проводника).
В классе CString данные хранятся в кодировке Unicode, а в файле они записаны в кодировке Windows 1251. По этой причине, если вы просто будете записывать данные в файл с помощью оператора вида
MyFile<<HVec[i].GetBuffer()<<'\n';
то в файле обнаружите только целые числа.
Учитывая сказанное, вот вам текст корректной функции записи в файл:
|
С описанием функции WideCharToMultiByte() ознакомьтесь в разделах «Работа со строками» и «Русификация приложений» [3].
Подобным чином создайте обработчик команды ФайлСохранить как, в котором вы добавите диалоги по выбору новых имен файлов для записи массивов.
Убедитесь в том, что вы научили программу сохранять файлы, и возгордитесь собой, но не очень сильно.
Шаг 5. Использование управляющего элемента RichEdit2 для отображения текста в формате RTF (Rich Text Format – расширенный текстовый формат). Было бы неплохо иметь возможность просмотра текстов обрабатываемых файлов в программе. Для этого можно использовать элемент RichEdit2, который, в частности, позволяет отображать многострочный текст с использованием такого форматирования, которое предоставляет хорошо известный вам редактор Word.
Начать можно с добавления в функцию InitInstance() класса приложения метода AfxInitRichEdit2():
BOOL CGenApp::InitInstance()
{
CWinApp::InitInstance();
EnableTaskbarInteraction(FALSE);
// Для использования элемента управления RichEdit2 требуется метод
// AfxInitRichEdit2()
AfxInitRichEdit2();
// ...
Если этого не сделать, то воспользоваться элементом управления RichEdit2 не получится.
Далее разместите на форме два элемента управления RichEdit2 примерно так, как показано на рис. 4.
|
Рис. 4. Элементы RichEdit2 на форме
Вызовите для «левого» элемента RichEdit2 контекстное меню и выполните в нем команду Add Variable. Задайте имя m_Rich1 (рис. 5) и убедитесь в том, значения остальных полей соответствуют указанным на рис. 5.
|
Рис. 5. Окно задания имени связанной переменной
Аналогичным образом задайте имя и для другого элемента – m_Rich2. Вы уже скумекали, что m_Rich1 и m_Rich2 представляют собой имена объектов класса CRichEditCtrl и мы будем их использовать для работы с элементами RichEdit2. Описания этих имен вы должны выявить в заголовочном файле класса вида – проверьте! Запустите приложение на выполнение, попробуйте изменять размеры окна для того, чтобы посмотреть, влияет ли это на размеры и положение элементов RichEdit2.
Задать требуемые значения свойств элементов RichEdit2 можно с помощью окна свойств, а можно задать их в обработчике события WM_CREATE (не в конструкторе!). Для этого создайте обработчик этого события и наполните его таким кодом:
|
Единственное свойство, значение которого надо установить в окне свойств элемента – это Visible. Задайте ему значение false для обоих элементов.
А вот для того, чтобы заставить элементы RichEdit2 занимать всю клиентскую часть окна независимо от его размеров, надо создать обработчик события WM_SIZE класса вида и наполнить его таким кодом:
|
Запустите приложение на выполнение и воочию убедитесь в том, что при изменении размеров окна элементы RichEdit2 также масштабируются. Обратите также внимание на то, что в элементы можно вводить текст, хотя это нам и не нужно (рис. 6).
|
Рис. 6. Окно с элементами RichEdit2
Шаг 6. Вывод содержимого файлов в элементы RichEdit2. Вывод текста в RichEdit2 выглядит достаточно просто, например:
m_Rich1.SetWindowText(_T("Это первая строка"));
Ожидаемо в элементе мы увидим приведенную строку текста. Однако, если мы выполним два оператора
m_Rich1.SetWindowText(_T("Это первая строка"));
m_Rich1.SetWindowText(_T("А это вторая строка"));
то увидим в элементе только вторую строку. Если нам очень хочется отобразить в RichEdit2 несколько строк текста, то надо все эти строки поместить в один объект CString и передать его в качестве фактического параметра функции SetWindowText(), позаботившись при этом о добавлении в строку признака конца строки ‘\n’. Пример:
CString Test;
Test=_T("Это первая строка");
Test+='\n';
Test+=_T("А это вторая строка");
Test+='\n'; // при необходимости
m_Rich1.SetWindowText(Test);
В этом случае мы действительно увидим в RichEdit2 две строки текста. Учитывая эту ценную информацию, доработайте функции чтения файлов или, еще лучше, напишите отдельные функции для вывода содержимого прочитанных файлов в RichEdit2. Если вы все это проделаете, то будете вознаграждены видом своего приложения, подобным рис. 7.
|
Рис. 7. Окно с элементами RichEdit2 и текстами файлов
У вас может возникнуть вполне законный вопрос: а зачем нам нужно отображать содержимое файлов в элементах RichEdit2? Ответ может быть таким.
Во-первых, элемент RichEdit2 очень полезен при необходимости отображения текста любого объема в приложении.
Во-вторых, этот элемент имеет массу возможностей как по настройке его свойств (выбор шрифтов, размеров и начертаний символов, цветов, стилей и т.д. и т.п.), так и по редактированию текста пользователем и/или программно. Например, те билеты, которые вы получаете на модулях, генерируются программным образом из текстового документа с тестовыми заданиями, подготовленного в редакторе Word.
В-третьих, если вы снабдите свое приложение функциями, которые будут выводить в эти элементы содержимое массивов строк, в которых содержится содержимое обрабатываемых файлов, то сильно облегчите свою работу по отладке приложения, так как сможете в любой момент времени отображать ход обработки данных.
На этом заканчивается первая часть работы и вы можете ее сдать преподавателю, если хотите получить хорошие баллы.
