Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
New Документ Microsoft Word (3).doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
1 Мб
Скачать
☆

16.2.Вариант 2 Сценарий выполнения работы

Любой юзер знает, что список файлов, выводимый в окне Проводника Windows, можно сортировать путем щелчка по заголовку соответствующего столбца таблицы. В данной работе приводится сценарий создания приложения, в котором на основе управляющего элемента List Control (MFC класс CListCtrl) показана последовательность создания подобного списка.

Шаг 1. Создайте заготовку приложения, включающего поддержку MFC и архитектуры документ-вид. В качестве базового для класса вида выберите класс CFormView для того, чтобы можно было в окне приложения разместить управляющий элемент List Control. Предполагается, что проекту присвоено имя SL (Sort List).

Шаг 2. В окне приложения разместите управляющий элемент List Control и задайте для него значение свойства View==Report. Можно собрать приложение, запустить его на выполнение и убедиться в том, что среда MVS способна создавать работоспособные каркасы приложений (рис. 1). Строки и столбцы списка, по сути дела таблицы, нам придется создавать путем написания программного кода, а не путем задания каких-либо свойств управляющих элементов, как это реализовано в Delphi.

Рис. 1. Окно приложения с элементом List Control

Шаг 3. Создание столбцов таблицы. Первым делом с помощью мастера создадим переменную objList (рис. 2) для получения доступа к нашему управляющему элементу список как к экземпляру класса CListCtrl.

Рис. 2. Добавление переменной objList, являющейся объектом класса CListCtrl

Далее добавим в функцию CSLView::OnInitialUpdate() код, который задает число столбцов в списке и их наименования, отображаемые в заголовке списка:

Назначение и смысл членов структуры LV_COLUMN можно (и нужно!) узнать из MSDN.

Замечание. Если бы элемент List Control был размещен в диалоговом окне, то приведенный выше код надо было бы добавить в функцию OnInitDialog() класса диалогового окна.

Если Вы теперь запустите приложение на выполнение, то увидите пока еще пустую таблицу, но уже с наименованиями столбцов (рис. 3).

Рис. 3. Список с добавленными столбцами

Шаг 4. Описание структур данных для хранения элементов списка. Для того чтобы впоследствии можно было сортировать элементы списка по выбранному столбцу, надо сначала значения этих элементов каким-то образом задать в массиве структур и разместить в списке (классе CListCtrl) указатели на них. В дальнейшем для сортировки списка мы будем просто сортировать этот массив по выбранному компоненту структуры. Так как в список можно заносить только строковые данные, то компоненты структуры должны иметь строковый тип либо их надо преобразовать в строковый тип перед занесением в список.

В соответствии с архитектурой документ-вид мы должны размещать данные в классе документа. Предварительно создайте заголовочный файл Student.h с таким содержимым:

Для того чтобы файл Student.h был добавлен средой MVS-2005 в перечень файлов проекта, создайте его с помощью команды ProjectèAdd New Item.

Тип TStudent представляет собой структуру из двух указателей на строки (null-terminated string).

Подключите файл Student.h с помощью директивы include в заголовочный файл документа SLDoc.h и добавьте в класс документа массив (вектор) структур:

Проанализировав приведенный код, Вы легко обнаружите, что в классе документа мы создали массив (вектор) структур TStudent, воспользовавшись шаблонным классом vector.

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

Попробуйте компилировать приложение. Есть ошибки компиляции? Может быть, надо включить в файл SLDoc.h еще какой-нибудь заголовочный файл с объявлением шаблонного класса vector и директиву using namespace std;?

Шаг 5. Ввод данных из текстового файла и занесение их в список. Создайте текстовый файл такого, например, содержания:

Как Вы уже догадались, каждая запись файла содержит фамилию студента и его отметку, допустим, среднюю или лучшую. Для изложения сценария этого достаточно, не так ли?

Теперь надо прочитать эти данные из (текстового) файла. Для этого предлагается создать в классе вида CSLView обработчик события ID_FILE_OPEN, которое генерируется системой при выборе пользователем команды меню FileèOpen. Создайте этот обработчик и наполните его таким (самоочевидным?) кодом:

Для того чтобы от выполнения этой работы был толк, осмыслите приведенный программный код. Попробуйте компилировать приложение и запустить его на выполнение. Если будут ошибки – избавьтесь от них.

Когда Вам удастся собрать приложение и запустить его на выполнение, то окно приложения должно приобрести примерно такой вид, как на рис. 4. (Если это не так, то надо, естественно, приобрести новый компьютер, по крайней мере с полутораядерным процессором.)

Работа со списком, т.е. добавление новых строк, сводится к вызову одной из перегруженных функций CListCtrl::InsertItem(), которая собственно и вставляет новую строку. Версия функции CListCtrl::InsertItem() с единственным параметром типа LV_ITEM вставляет пустую строку, если компонент структуры LV_ITEM.pszText указывает на пустую строку, как в приведенном выше тексте функции CSLView::OnFileOpen(). Занесение данных в столбцы строки в данном примере выполняется с помощью функции CListCtrl::SetItemText(), первый параметр которой указывает на номер строки, а второй – на номер столбца. Попробуйте закомментировать строки с вызовом функции CListCtrl::SetItemText(), запустите приложение на выполнение и пощелкайте мышью в первом столбце строк таблицы. Несмотря на то, что список пустой, вы обнаружите присутствие пяти строк (рис. 5). С помощью функции CListCtrl::SetItemData() мы сохраняем в объекте objList указатели на данные, помещенные в соответствующую строку списка, что нужно только для последующей сортировки данных списка.

Рис. 4. Список с данными

Рис. 5. Список с пустыми строками

Приведенный в функции CSLView::OnFileOpen() способ вставки столбцов и строк и собственно заполнения списка конкретными данными не является единственно возможным. Класс CListCtrl предлагает много разных член-функций, которые позволяют выполнять со списком разнообразные операции, в том числе, например, помещать в список изображения. Читайте MSDN или шарьте в Интернете!

Шаг 6. Сортировка данных в списке. Вы хорошо знаете, что если в окне Проводника щелкнуть по заголовку какого-либо столбца со списком файлов, то список будет чудесным образом отсортирован по данному столбцу, что не только приятно, но и полезно. Выполним и мы такую сортировку. Для этого, как Вы догадываетесь, надо создать обработчик соответствующего события.

В окне ClassView выберите класс вида CSLView, вызовите для него окно свойств, в нем выберите вкладку Events, в ней раскройте ветвь IDC_LIST1 (если Вы не изменяли идентификатор списка CListCtrl) и уже в этой ветви создайте обработчик OnHdnItemclickList1() события HDN_ITEMCLICK (рис. 6). Текст обработчика наполните таким нехитрым содержанием:

Рис. 6. Добавление обработчика события HDN_ITEMCLICK

Если Вы попытаетесь компилировать приложение, то увидите сообщение об ошибке:

'SortFunc' : undeclared identifier

Первый параметр функции CListCtrl::SortItems() должен быть именем функции «обратного вызова» (callback function), которая должна выполнять сравнение сортируемых значений и возвращать его результат в виде целого числа. Как следует из MSDN, эта функция должна иметь такой формат:

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,

LPARAM lParamSort);

Функция сравнения CompareFunc() должна возвращать:

  • отрицательное значение, если первый параметр больше второго;

  • положительное значение, если первый параметр меньше второго;

  • нулевое значение при равенстве значений параметров.

Параметр lParam1 должен быть 32-битовым значением, ассоциированным с первым сравниваемым значением, а lParam2 – соответственно вторым. Это те величины, которые были указаны в члене lParam структуры LVITEM, когда они помещались в список. Параметр lParamSort такой же, как и второй параметр функции SortItems().

С учетом сказанного текст функции может быть таким:

Если Вас удивляет, что число хвостов студентов сравниваются с помощью функции strcmp(), предназначенной для сравнения строк текста, то вспомните, что число хвостов, как и фамилия, хранятся в виде строк текста (см. выше массив строк Data). Так как в ХАИ (пока) число хвостов студента не может превышать девяти (одна цифра), то такой подход работает. При большем числе хвостов начнутся глюки, для устранения которых необходимо будет преобразовывать строку в число и сравнивать уже числовые значения.

Запустите приложение на выполнение и убедитесь в том, что оно работает корректно, т.е. список выводится и сортируется.

Проверьте, что в окне Debug при запуске отладочной версии приложения нет сообщений об утечках памяти, т.е. содержащих текст «Detected memory leaks!». Если такие сообщения есть, то надо найти и устранить их причину, а иначе такое приложение постепенно украдет память Вашего компьютера, а преподаватель не зачтет лабу.

Список литературы

1. Круглински Д., Уингоу С., Шеферд Дж. Программирование на Microsoft Visual C++ для профессионалов/Пер. с англ. – СПб:Питер; М.: Издательско-торговый дом "Русская редакция", 2000. - 864с.

2. Холзнер С. Visual C++ 6: учебный курс – СПб.: Изд-во «Питер», 2000. – 576с.

3. Конспект лекций в файле VC_Lect.doc

4. Овсянник_Язык_С++_не_для_чайников.doc

Resource language - значение Русский

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)

#ifdef _WIN32

LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT

#pragma code_page(1251)

Resource language - значение Английский

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

LANGUAGE 9, 1

#pragma code_page(1252)

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