Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

VisualC_Studio_1 / Lab / lb_06

.htm
Скачиваний:
12
Добавлен:
21.03.2015
Размер:
165.37 Кб
Скачать

Круглински Д Лабораторная работа № 6

 

Тема: Использование элементов управления ActiveX. Стандартное диалоговое окно класса CFileDialog. Сортировка массива записей по выбранному полю.

 

            Одна из наиболее распространённых в программировании задач заключается в следующем: считать информацию из файла, некоторым образом её обработать и записать результат в другой файл. Решением этой задачи мы и займёмся.

            Из входного текстового файла прочитаем массив записей с тремя полями, отсортируем эти записи по одному из полей и запишем массив отсортированных записей в выходной текстовый файл.

            На экране массив записей удобно расположить в таблице, но среди стандартных элементов управления такого элемента нет; поэтому для представления табличных данных нам придётся использовать так называемый ActiveX-элемент.

 

Создание нового проекта с помощью генератора кода AppWizard

Создайте новый проект с именем MyPr06:

File > New > Project.

В качестве типа проекта Project types выберите MFC, в качестве Templates – MFC Application, укажите в разделе Location (Местоположение) свой директорий, заполните имя проекта Name: MyPr06 и щелкните ОК.

Затем

перелистните первую страницу, выбрав кнопку Next;

на странице Application type выберите Single document (однооконное приложение), для Visual Studio 2008 на этой же странице выберите «русский» язык;

перелистните следующие четыре страницы;

на странице Advanced Features проверьте, чтобы флажок ActiveX Controls был  установлен;

на странице Generated Classes для класса с именем CMyPr06View в качестве базового класса (Base class) выберите из списка CFormView. Нажмите кнопку Finish.

 

В свойствах проекта смените кодировку (см. лабораторную работу № 1).

 

Перейдите на вкладку ResourceView окна проектов.

Раскройте списки MyPr06.rs и Dialog. Дважды щелкните левой кнопкой мыши идентификатор IDD_MYPR06_FORM, и, когда перед Вами откроется пустое диалоговое окно MyPr06.rs (IDD...Form-Dialog), снова, теперь уже правой кнопкой мыши, щелкните идентификатор IDD_MYPR02_FORM. В открывшемся контекстном меню выберите команду Properties (Свойства).  В окне свойств диалога замените язык (Language) на русский (если он не указан там по умолчанию).

 

«Перевод» Главного меню на русский язык

Присутствие в приложении смешанного англо-русского «диалекта» - это наглядная демонстрация плохого вкуса программиста. На этот раз «переведём» Главное меню на русский язык.

 

            1. Откройте окно редактора ресурсов (вкладка ResourceView > список Menu > дважды щелкнуть левой кнопкой мыши IDR_MAINFRAME).

            2. Оставьте в Главном меню два пункта: File и View. В пункте File оставьте команды Open, Save as, Exit. Остальное удалите.

3. У каждой команды поочерёдно замените наименования (Caption) и подсказки (Prompt) русскими аналогами. У Вас должно получиться примерно так:

 

 

4. Займёмся согласованием Главного меню и панели инструментов.

Откройте окно редактора ресурсов (вкладка ResourceView > список Toolbar > дважды щелкнуть левой кнопкой мыши IDR_MAINFRAME).

5. Откройте окно свойств панели инструментов (вкладка ResourceView > список Toolbar > правой кнопкой мыши щелкнуть IDR_MAINFRAME и выбрать Properties). В окне свойств замените язык (Language) на русский (Russian) и закройте окно свойств.

            Удалим с панели инструментов «лишние» пиктограммы. Чтобы удалить пиктограмму, надо перетащить её мышью за пределы окна редактора ресурсов. У Вас должны остаться две пиктограммы, не считая чистой:

            В свойствах второй кнопки («дискета») смените идентификатор с ID_FILE_SAVE на ID_FILE_SAVE_AS.

6. Сохраните файл ресурсов MyPr06.rc на диске: вкладка ResourceView > Toolbar > правой кнопкой мыши щелкнуть IDR_MAINFRAME и выбрать Save MyPr06.rc.

7. Соберите приложение и запустите его на выполнение. Главное меню «заговорило» по-русски. Пощёлкайте команды в пункте «Вид», чтобы убедиться, что они работают.

 

Редактирование диалогового окна

            Откройте окно редактора ресурсов: MyPr06.rc - IDD_MYPR06_FORM... (вкладка Resource View > Dialog > IDD_MYPR07_FORM)

 

1. Чтобы Вам было удобнее работать с редактором ресурсов, можете, как описано в лабораторной работе № 2, растянуть окно диалога, включить режим сетки (кнопка Toggle Grid внизу на диалоговой панели инструментов), поменять шрифт и размер и т.д.

 

            2. Щелкнув левой кнопкой мыши надпись: TODO: Place form controls on this dialog, выделите ее, после чего удалите (клавиша Delete клавиатуры).

 

3. Установим в проект ActiveX-элемент управления FlexGrid, позволяющий работать с таблицей. Для этого выполните следующие действия:

3.1. откройте палитру элементов управления (пункт View Главного меню > ToolBox);

3.2. щёлкнув правой кнопкой мыши в любом месте палитры, откройте контекстное меню, в котором выберите команду: Choose Item;

            Перед Вами открылось окно Choose Toolbox Items. Перейдите на вкладку COM Components этого окна.

            Здесь хранится масса полезных элементов управления, позволяющих работать с анимацией, со звуком, с сетью Интернет и т.д. В настоящее время нас интересует элемент Microsoft FlexGrid Control, version 6.0:

 

Внимание!!! Если этого элемента в предлагаемом Вам списке нет, то, скорее всего, присутствует элемент VideoSoftFlexArray Control.

 

Поставив «галочку», выберите этот элемент и нажмите OK.

В результате этих действий в самом низу палитры Toolbox элементов управления появился новый элемент.

 

            4. Разместите на диалоговом окне элементы управления.

 

4.1. Перетащите мышью с палитры в создаваемое диалоговое окно только что добавленный элемент «Таблица» (Microsoft FlexGrid Control, version 6.0).

В свойствах (правая кнопка мыши) этого элемента установите количество столбцов (параметр Cols) равным 4. Что касается количества строк (параметр Rows), то его пока не меняйте, - это значение мы изменим программно, после того, как будет считана информация из входного файла.

4.2. Добавьте группирующую рамку . В её свойствах смените наименование Caption на «Сортировать»;

4.3. Внутри группирующей рамки разместите три переключателя .

            У первого в свойствах смените название (Caption) - «по первому полю», у второго - «по второму полю», у третьего - «по третьему полю». Вернитесь к свойствам первого переключателя и, поставив «галочку», установите для него свойство Group равным True.

            Результат Вашей работы должен выглядеть примерно так:

 

 

5. Сохраните файл ресурсов MyPr06.rc на диске: вкладка ResourceView > Dialog > правой кнопкой мыши щелкнуть IDD_MYPR06_FORM и выбрать Save MyPr06.rc.

 

Добавление переменных класса CMyPr06View

Перейдите на вкладку Class View окна проектов и раскройте список MyPr06 classes. Щелкните правой кнопкой мыши CMyPr06View и в открывшемся контекстном меню выберите Add > Add Variable.

В результате перед Вами появилось одноименное окно.

Поставьте «галочку» слева от Control variable, объявив тем самым, что переменная связана с управляющим элементом.

В списке Control ID выберите идентификатор управления IDC_MSFLEXGRID1.

 В качестве имени переменной Variable name введите m_strgrid. Ничего больше не меняя, нажмите Finish.

 

 

Начальная инициализация таблицы

Откройте файл MyPr06View.cpp и в конец функции OnInitialUpdate добавьте строки:

 

// Устанавливаем ширину столбцов таблицы

m_strgrid.put_ColWidth(0,600);

m_strgrid.put_ColWidth(1,1800);

m_strgrid.put_ColWidth(2,1200);

m_strgrid.put_ColWidth(3,800);

 

// Создаём заголовки столбцов таблицы

m_strgrid.put_Row(0); // Нулевая строка

m_strgrid.put_Col(0); m_strgrid.put_Text("№ п/п");

m_strgrid.put_Col(1); m_strgrid.put_Text("ФАМИЛИЯ");

m_strgrid.put_Col(2); m_strgrid.put_Text("ИМЯ");

m_strgrid.put_Col(3); m_strgrid.put_Text("ОЦЕНКА");

Внимание!!! Если Вы загрузили элемент VideoSoftFlexArray Control, то во всех командах поменяйте сочетание букв «put_» (со строчной буквы, с чертой) на «Set» (с прописной буквы, без черты).

 

Соберите приложение и запустите его на выполнение. Убедитесь, что у столбцов изменилась ширина, а также появился заголовок.

 

 

 

Чтение файла

Откройте и посмотрите файл VisualC_Part01\FilesForStud\StudPmi.txt. Здесь хранятся записи с информацией о фамилии, имени и оценке студента. Первая строка не содержит полезной информации. Она просто сообщает пользователю, какие данные здесь хранятся. Признаком конца файла служит строка «−1». Наша задача на данном этапе - прочитать информацию из этого файла и разместить её в таблице m_strgrid. Закройте файл StudPmi.txt и скопируйте его в свою папку MyPr06\MyPr06, т.е. туда, где находятся файлы с расширениями «.cpp» и «.h».

Как Вы знаете, в пункте «Файл» Главного меню есть команда «Открыть». Однако всё, на что она способна - запомнить и вернуть строку символов, представляющую собой путь к файлу и его имя. Так что нам предстоит эту команду переопределить.

 

1. Отредактируйте файл MyPr06View.cpp. Сразу после макросов перед описанием класса CMyPr06View добавьте строки:

 

#define MAX_NODES                    101      // Максимальное число записей в файле

#define NODE_FIELDS                  3          // Количество полей в записи

 

int NodesNumber=0;                         // Реальное число записей в файле

struct MY_NODE                             // Структура "Запись"

{

            char surname[24];       // Фамилия

            char name[18];            // Имя

            int        ball;                 // Оценка

}                     

            myNode[MAX_NODES];    // Массив записей

 

Таким образом, мы определили массив записей myNode, как глобальную переменную.

 

2. В начало файла MyPr06View.cpp, после всех операторов #include непосредственно перед операторами #define вставьте строки:

 

#include "fstream"                 // Вставить перед: #define MAX_NODES            101

using namespace std;

 

Тем самым Вы подключили библиотеку файловых потоков для работы с входными и выходными файлами.

 

            3. Создадим вспомогательную закрытую (private) функцию UpdateFlexGrid (Обновить таблицу) типа void, которая будет «переносить» данные из массива myNode в таблицу.

Перейдите на вкладку Class View окна проектов и щелкните правой кнопкой мыши строку CMyPr06View. В открывшемся контекстном меню выберите пункт Add > Add Function. Заполните одноимённое окно так, как показано на рисунке и нажмите ОК.

 

 

Нажмите ОК. В заготовку внесите текст функции:

 

int i; CString lin;

if (NodesNumber>0) // если массив не пустой

{

            for (i=0; i<NodesNumber; i++)

            {          // Выводим информацию в таблицу

m_strgrid.put_Row(i+1);

                        m_strgrid.put_Col(0);

                                   lin.Format("%d",i+1); m_strgrid.put_Text(lin);

                        m_strgrid.put_Col(1);

                                   m_strgrid.put_Text(myNode[i].surname);

                        m_strgrid.put_Col(2);

                                   m_strgrid.put_Text(myNode[i].name);

                        m_strgrid.put_Col(3);

                                   lin.Format("%d",myNode[i].ball); m_strgrid.put_Text(lin);

            }

}

 

4. Создадим процедуру - обработчик команды «Открыть». Это будет обработчик сообщения COMMAND для идентификатора ID_FILE_OPEN.

            4.1. Откроем редактор ресурса «Главное меню»: ResourceView > Menu > дважды щелкнуть левой кнопкой мыши IDR_MAINFRAME.

            4.2. Добавим обработчик: щёлкните правой кнопкой мыши ячейку «Открыть» и в открывшемся контекстном меню выберите команду Add Event Handler (Добавить Событие).

            В окне Event Handler Wizard выберите класс CMyPr06View, убедитесь, что в списке Message type указано сообщение COMMAND и нажмите кнопку Add and Edit (Добавить и Редактировать).

В текст функции OnFileOpen внесите строки:

 

char lin[81];                            // Введённая новая строка

char surname_new[24];          // Фамилия в новой записи

char name_new[18];               // Имя в новой записи

int        ball_new;                    // Оценка в новой записи

 

// Открываем стандартное окно диалога

CFileDialog dlg(TRUE,NULL,"*.txt",NULL,

                        "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*|");    

 

if (dlg.DoModal()==IDOK)

{

ifstream inFile;           // объявляем файловую переменную

inFile.open(dlg.GetFileName());       // открываем файл

if (!inFile)

     {

            AfxMessageBox("File open error");

exit(1);

      }

inFile.getline(lin,sizeof(lin)); // пропускаем первую строку с пояснениями

inFile >> surname_new >> name_new >> ball_new;           // читаем строку из файла

 

while ( (atoi(surname_new) != -1) && (NodesNumber<MAX_NODES) )

{

            // Формируем запись

            strcpy(myNode[NodesNumber].surname,surname_new);

            strcpy(myNode[NodesNumber].name,name_new);

            myNode[NodesNumber].ball=ball_new;

            NodesNumber++;                  // номер следующей записи

// читаем следующую строку из файла

            inFile >> surname_new >> name_new >> ball_new;

}

inFile.close();              // закрываем файл

 

if (NodesNumber>0)

{

            // Устанавливаем количество строк в таблице

            m_strgrid.put_Rows(NodesNumber+1);                             

            UpdateFlexGrid(); // выводим информацию в таблицу

            m_strgrid.SetFocus();

}

}

 

Пояснения

3.1. В конструкторе стандартного диалогового окна

 

CFileDialog dlg(TRUE,NULL,"*.txt",NULL,

                        "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*|");    

 

первый параметр TRUE сообщает программе о том, что мы хотим открыть окно «Open File». Чтобы открылось окно «Save File», надо положить первый параметр равным FALSE.

            Третий параметр ("*.txt") представляет собой текст, который появится в разделе «Имя файла» окна «Open File» (если Вы хотите, чтобы эта строка оставалась пустой, задайте третий параметр равным NULL).

             Строка, являющаяся последним параметром, задаёт фильтр, т.е. те типы файлов, которые будут указаны в разделе «Тип файлов».

 

Что касается остальных параметров, Вы можете познакомиться с ними, открыв справочное руководство.

 

            3.2. Чтение из файла производится до тех пор, пока не достигнут конец файла (признаком конца служит строка «−1») и при этом реальное количество записей NodesNumber не превышает максимальное значение MAX_NODES.

 

4. Соберите приложение и запустите его на выполнение. С помощью команды «Открыть» пункта «Файл» Главного меню откройте файл StudPmi.txt. Если Вы всё сделали правильно, Ваша таблица заполнилась.

 

Сортировка

            В качестве метода сортировки массива n записей выберем сортировку Шелла, которая является усовершенствованной разновидностью сортировки включением.

 

            Сортировка включением («путем вставок» по Д.Кнуту) состоит в следующем: выбирается некоторый элемент, сортируются другие элементы, после чего выбранный элемент “включается”, т.е. устанавливается на свое место среди других элементов.

 

Рассмотрим подробнее простейший метод, использующий этот принцип, - метод простых вставок. Будем сравнивать по очереди ключ i-й записи с ключами записей: i-1-й, i-2-й, … до тех пор, пока не обнаружим, что i-ю запись следует вставить между записями j-й и j+1-й. Подвинув записи с

Соседние файлы в папке Lab