Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ISVP_Labs_16_17.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
8 Мб
Скачать
☆

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.

В-третьих, если вы снабдите свое приложение функциями, которые будут выводить в эти элементы содержимое массивов строк, в которых содержится содержимое обрабатываемых файлов, то сильно облегчите свою работу по отладке приложения, так как сможете в любой момент времени отображать ход обработки данных.

На этом заканчивается первая часть работы и вы можете ее сдать преподавателю, если хотите получить хорошие баллы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]