Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МетодичкаФИН kosh.doc
Скачиваний:
29
Добавлен:
15.02.2016
Размер:
3.16 Mб
Скачать

Практическое занятие №7 Тема: «Однодокументное приложение для работы с файлами. Полосы прокрутки. Использование модальных диалоговых окон».

7.1. Простой пример однодокументного приложения для чтения текстового файла.

Создайте однодокументное приложение (Single Document).

В окне Solution Explorer раскройте раздел Header Files и сделайте мы­шью двойной щелчок по имени файла View.h, в рабочей области откро­ется текст файла. Этот файл содержит объявление класса C…View. В этом классе объявите объект:

CString text;

Откройте файл …View.cpp. Найдите функцию OnDraw(…).

Измените текст функции как показано ниже.

void CFile1View::OnDraw(CDC* pDC)

{

CRect rect; // Объявляем прямоугольник

GetClientRect(&rect);

// сопоставляем прямоугольник с клиентской (рабочей) областью окна

if(!text.IsEmpty())

pDC->DrawText(text,rect, DT_LEFT);

else pDC->TextOut(10, 10, “Откройте файл”);

// Если текст файла прочитан, выводим его на экран

}

В окне Resource View раскройте пункт Menu. Сделайте двойной щелчок мышью по идентификатору IDR_MAINFRAIM. В рабочей области откроется меню приложения в режиме редактирования.

Сделайте щелчок правой кнопкой мыши по командеFile|Open. В поя­вив­шемся контекстном меню выберите пункт Add Event Handler. Появится окно для создания функции-обработчика выбранной команды.

Установите класс C…View, оставьте сообщение COMMAND и щелкните по кнопке Add and Edit. Добавьте код в функцию OnFileOpen как показано ни­же.

void CFile1View::OnFileOpen()

{

static char szFilter[] = " Header Files (*.h)|*.h|\

Source Files (*.cpp)|*.cpp|\

Text Files (*.txt;*.dat)|*.txt; *.dat|\

All Files (*.*)|*.*||";

CFileDialog dlgf(true,"txt", "*.h",OFN_EXPLORER, szFilter );

if (dlgf.DoModal()==IDOK)

{

CString name = dlgf.GetFileName();

CStdioFile file;

file.Open(name, CFile::modeRead);

BOOL flag;

CString str;

text.Empty();

if (file.m_pStream)

{

do

{// Считываем строки файла и создаем из них объект text:

flag = file.ReadString(str);

if (flag) text+=(str+'\n');

}while (flag);

Invalidate(); // Вызывается функция OnDraw(…)

}

}

}

Запустите приложение и откройте какой-нибудь длинный текстовый файл. Какие Вы видите недостатки отображения текста в окне приложения?

7.2. Простой пример однодокументного приложения, использующего класс документа для чтения файла и полосы прокрутки для отобра­же­ния файла в окне.

Создайте однодокументное приложение (Single Document). При созда­нии проекта, нажимая кнопку <Next>, дойдите до окна Generated Classes (см. рисунок на следующей странице). В этом окне задайте для класса C…View ба­зовый класс CScrollView. Этот класс обеспечивает возможность исполь­зо­вания полос прокрутки.

Откройте файл …Doc.h и в классе в области public: объявите объект:

CString text;

Откройте файл …Doc.cpp и найдите функцию Serialize(). Эта функция спе­циально предназначена для работы с файлами и автоматически вызы­ва­ется при выборе команды File|Open или File|Save. Параметром функции Serialize() является объект ar, который связывается с файлом, открытым поль­зо­вателем.

Окно для выбора файла создается автоматически.

Отредактируйте код функции как показано ниже.

void CFileDoc::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{

// Эта часть работает при сохранении файла

}

else

{

// Эта часть работает при открытии файла для чтения:

CString str; // Строка текста

// Считываем данные с помощью объекта ar также как с помощью обычного файла

while (ar.ReadString(str))

// считываем строку, пока файл не закончится

text += (str + '\n'); // добавляем строку к тексту

}

}

Откройте файл …View.cpp и найдите функцию OnInitialUpdate(). В этой функции можно задать размеры полос прокрутки (в пикселях). Если раз­мер полосы про­крутки больше, чем соответствующий размер окна, полоса про­крутки будет создана.

Отредактируйте код функции как показано ниже:

void CFileView::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

CSize sizeTotal;

// TODO: calculate the total size of this view

sizeTotal.cx = 1000; // Размер горизонтальной полосы прокрутки

sizeTotal.cy = 10000; // Размер вертикальной полосы прокрутки

SetScrollSizes(MM_TEXT, sizeTotal); // Создание полос прокрутки

}

Найдите функцию OnDraw() и отредактируйте код функции как пока­за­но ниже:

void CFileView::OnDraw(CDC* pDC)

{

CFileDoc* pDoc = GetDocument();// Получаем указатель на документ

ASSERT_VALID(pDoc);

if (!pDoc)

return;

CFont MyFont; // Определяем шрифт

MyFont.CreateFont(20, 0,0,0,100, 0, 0, 0, 0,

0, 0, 0, 0, "Times New Roman");

pDC->SelectObject(&MyFont);

pDC->SetTextColor(RGB(0, 100, 100)); // Цвет текста

CRect rect; // Прямоугольник для вывода текста

GetClientRect(&rect);

// размеры прямоугольника делаем равными размерам полос прокрутки:

rect.right = 1000;

rect.bottom = 10000;

if (!pDoc->text.IsEmpty())// Если файл прочитан (текст не пустой)

pDC->DrawText(pDoc->text, rect, DT_LEFT);

// Выводим его на экран (в прямоугольник rect)

}

Запустите приложение и откройте какой-нибудь длинный файл (например ReadMe. txt ). Проверьте работу полос прокрутки.

7.3. Программа, которая считывает текст из файла и выводит на экран строку с заданным номером. Номер строки задается с помощью мо­даль­ного диалогового окна, которое появляется по команде главного меню.

Создайте однодокументное приложение (Single Document). При созда­нии проекта, нажимая кнопку <Next>, дойдите до окна Generated Classes (см. пример 7.2.). В этом окне задайте для класса C…View базовый класс CScrollView. Этот класс обеспечивает возможность исполь­зования полос про­крутки.

Откройте файл …Doc.h и в классе в области public: объявите объекты:

CStringArray text; // массив для хранения текста

CString LongStr; // самая длинная строка файла

CString FileName; // имя файла

CString ScreenText; // объект для вывода текста на экран

Откройте файл …Doc.cpp и найдите функцию Serialize(). Отредактируй­те код функции как показано ниже.

void C…Doc::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{

// TODO: add storing code here

}

else

{

CString str; // строка для чтения файла

text.RemoveAll();// Очищаем массив

LongStr.Empty();

while (ar.ReadString(str))

// пока не достигнут конец файла, считываем строку из файла

{

if (LongStr.GetLength()< str.GetLength())

LongStr = str;

// находим самую длинную строку файла

str.Replace("\t"," ");

// заменяем знаки табуляции пробелами

text.Add(str); // добавляем считанную строку в массив

}

CFile* fp = ar.GetFile();// получаем указатель на файл

FileName = fp->GetFileName();// получаем имя файла

ScreenText = "Файл " + FileName + '\n';

// имя файла будем выводить перед текстом файла

UINT count = (UINT)text.GetSize(); // определяем размер файла

for (UINT i = 0; i< count ; i++) // проходим по массиву

ScreenText += text[i] + '\n';

// добавляем строку в объект, который будет выводиться на экран

}

}

Откройте файл …View.h и вставьте в класс объявление количества строк файла:

UINT count;

Откройте файл …View.cpp. Найдите функцию OnDraw() и отредакти­руй­те код функции как пока­за­но ниже:

void C…View::OnDraw(CDC* pDC) // Снимите знаки комментария !!!

{

C…Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

CFont MyFont;

MyFont.CreateFont(17, 0,0,0,100, 0, 0, 0, 0,

0, 0, 0, 0, "Courier");

pDC->SelectObject(&MyFont); // Установили шрифт

CSize size = pDC->GetTextExtent(pDoc->LongStr);

// Определили ширину самой длинной строки (в пикселях)

count = (UINT)pDoc->text.GetSize();

// Определили количество строк текста

if (count) // если текст прочитан (кол-во строк не равно нулю)

{

CSize sizeTotal; // размеры полос прокрутки

sizeTotal.cx = size.cx + 10;

// размер горизонтальной полосы прокрутки

sizeTotal.cy = int(size.cy * (count+1)+10);

// размер вертикальной полосы прокрутки

CRect rect;

GetClientRect(&rect);

// прямоугольник, соответствующий клиентской области окна

CSize sizeSym = pDC->GetTextExtent("T");

// Размеры одного символа

SetScrollSizes(MM_TEXT, sizeTotal, rect.Size(), sizeSym); // установили размеры полос прокрутки

rect.bottom = max(600, sizeTotal.cy);// высота области вывода

rect.right = max(800, sizeTotal.cx); // ширина области вывода

pDC->DrawText(pDoc->ScreenText, rect, DT_LEFT);

// выводим результат на экран

}

else pDC->TextOut(10,10, "Откройте файл");

}

В окне Solution Explorer на вклад­ке Resource View щелкните правой кноп­кой мыши по строке Dialog и в поя­вив­шем­ся контекстном меню вы­бери­те Insert Dialog. Спроектируйте появив­ше­еся диалоговое окно как по­казано на ри­сун­ке.

Щелкните правой кнопкой мыши по какому-либо участку окна, не за­ня­то­му элементами управления. В появившемся контекстном меню выберите Add class. Появится диалоговое окно, в котором нужно задать имя класса, который будет описывать наше вспомогательное окно. Задайте имя класса CDlg как показано на рисунке.

Впроект автоматически будут добавлены два файла:Dlg.h и Dlg.cpp.

Откройте файл …View.h и перед описанием класса C…ScrollViewвставьте директиву:

#include "Dlg.h" // Здесь содержится описание класса CDlg

В окне Solution Explorer на вкладке Resource View двойным щелчком мы­ши по идентификатору нового окна IDD_DIALOG1 откройте опять окно в режиме проектирования.

Щелкните правой кнопкой мыши по окну редактирования, в котором мы будем задавать номер строки, выберите в контекстном меню Add variable и свяжите с этим окном переменную n типа UINT.

В окне Solution Explorer на вкладке Resource View раскройте пункт Menu. Выделите идентификатор меню IDR_MAINFRAME. Перейдите в окно свойств меню. Если этого окна нет, нажмите Alt+Enter. В свойствах меню ус­тановите русский язык.

Сделайте двойной щелчок по идентификатору IDR_MAINFRAME. На рабочей поверхности откроется меню в режиме проектирования.

На рабочей поверхности сделайте щелчок правой кнопкой мыши по иде­н­тификатору кнопки Help. В контекстном меню выберите Insert New. В меню будет вставлена новая кнопка (команда). В свойствах этой кнопки задайте:

Caption

Задача

Popup

false

ID

ID_Task

Щелкните правой кнопкой мыши по кнопке “Задача” и выберите в кон­текстном меню Add Ivent Handler. Появится окно, в котором мы зададим об­работчик для новой команды.

Всписке классов установите имя классаC…View. В однодокументных приложениях все кнопки посылают сообщение COMMAND. Имя функции мастер сгененрирует автоматически. Нажмите кнопку Add and Edit.

Отредактируйте новую функцию как показано ниже:

void CFileScrollView::OnTask()

{

C…Doc* pDoc = GetDocument(); // получили указатель на объект докмента

CDlg dlg; // объект, описывающий диалоговое окно

if (dlg.DoModal() == IDOK) // Если пользователь задал номер строки

{

UINT i = dlg.n; // считываем номер

UINT size =(UINT)pDoc->text.GetSize();

// определяем размер текста

if (i < size) // Если задан допустимый номер

pDoc->ScreenText.Format("%i - я строка файла: \n %s", i, pDoc->text[i-1]); /* выводим строку на экран (при работе с пользова­те­лем используем нумерацию строк, начиная с1) */

else

pDoc->ScreenText = "Нет такой строки в файле";

Invalidate();// Выводим результат на экран

}

}

/* Для того, чтобы иметь возможность просмотреть исходный текст файла, добавим об­ра­ботчик для кнопки File|Recent File. Откройте меню в режиме проектирования и сделайте щелчок правой кнопкой мыши по кнопке <Recent File>. Выберите в контекстном меню Add Event Handler. В появившемся окне установите класс C…View, остальные параметры оставьте по умолчанию. Отредактируйте код функции как показано ниже */

void CFileNewWidthView::OnFileMruFile1()

{

C…Doc* pDoc = GetDocument();// Указатель на объект документа

pDoc->ScreenText.Empty();

for (UINT i = 0; i< count ; i++) // Проходим по массиву строк

pDoc->ScreenText += pDoc->text[i] + '\n';

// добавляем строки текста в объект для вывода на экран

Invalidate();// Выводим результат на экран

}