КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Сценарий выполнения работы. В качестве заготовки приложения предполагается использовать проект FRM из первой части работы
В качестве заготовки приложения предполагается использовать проект FRM из первой части работы. Шаг 1. Добавление команд меню. Добавьте тему Студент главного меню и включите в нее команды, приведенные в табл. 1. (Здесь предполагается, что Вы как будто используете класс CStudent, хотя на самом деле у Вас должен быть другой класс, который Вы выбрали самостоятельно.) Назначьте командам меню идентификаторы в соответствии с табл. 1. Разумеется, Вы можете присвоить командам меню любые идентификаторы, но принято использовать заглавные (и только английские) буквы и включать в идентификатор имя команды главного меню. В меню Edit у Вас по-прежнему должна быть одна команда Clear All (никто не мешает заменить ее на Очистить все), которая будет удалять весь список студентов. Замечание 1. Присутствие в меню пунктов, соответствующих кнопкам панели инструментов, вообще говоря, не обязательно. (ИС позволяет создавать обработчики команд панели инструментов так же, как и команд меню.) Но большинство Windows-приложений позволяет вызывать все команды посредством меню, поэтому лучше не обманывать ожиданий пользователей (и преподавателя тоже).
Таблица 1 Команды меню Студент и соответствующие им кнопки
Шаг 2. Добавление кнопок на панель инструментов. На вкладке Resource View выберите папку Toolbar, а в ней сделайте двойной клик ЛКМ по идентификатору IDR_MAINFRAME_256 (а не IDR_MAINFRAME). В ответ на сообщение «The bitmap for this toolbar must be adjusted to use this size. Adjust the bitmap to fit?» не спорьте со средой, кликните ОК, так как в противном случае Вам не удастся редактировать кнопки на панели инструментов. Замечание. При редактировании кнопок на панели инструментов Вам может понадобиться команда ImageèToolbar Editor, если редактор не отображает кнопки по одной для редактирования. Удалите из панели инструментов приложения (ресурс Toolbar) все кнопки, кроме первых трех, и добавьте новые в соответствии с табл. 1. Не пытайтесь изменить размеры кнопок – из этого ничего путного не выйдет. Для удаления кнопки (любой, кроме последней «пустой») просто вытащите ее из панели инструментов куда-нибудь вниз или вверх. Присвойте кнопкам ресурсные идентификаторы в соответствии с табл. 1. При создании изображений на кнопках удобно использовать команды редактирования Copy, Paste, Flip vertical и др. из контекстного меню. Надпись на кнопке (которая на форме, а не на панели инструментов) «Принять» измените на «Очистить», а «Ввод данных о студенте» – на «Данные о студенте». Теперь окно приложения должно принять вид, похожий на рис. 1.
Рис. 1. Вид окна приложения
Назначение кнопки «Очистить» – очистка полей ввода фамилии и отметки студента. Кнопка «Вставить новую запись» предназначена для вставки в список новой записи о студенте. В какую позицию списка? В текущую, само собой. Команда Clear All в меню Edit удаляет (должна!) из списка все записи и очищает поля – фамилия и отметка – в окне представления.
Шаг 3. Модификация класса CStudent. Код класса оставим прежним, только в конец Student.h надо добавить описание: typedef CTypedPtrList<CObList, CStudent*> CStudentList;
Это описание надо поместить действительно в конец файла Student.h, вне тела класса. Оно вводит тип CStudentList, который представляет собой коллекцию типизированных указателей на класс CStudent. Позже в классе документа мы объявим переменную (имеется ввиду член класса «документ») m_studentList типа CStudentList, которая и будет содержать список студентов.
Шаг 4. Генерация заготовок обработчиков команд меню Студент. Для того чтобы сгенерировать обработчики команд этого меню (они же будут вызываться и с помощью соответствующих кнопок, так как у них одинаковые идентификаторы) надо, как обычно, в окне ClassView выбрать класс вида CFRMView, вызвать для него окно свойств (Alt+Enter) и в этом окне выбрать вкладку Events и в ней, в ветви Menu Commands, найти идентификатор нужной темы меню и для него сгенерировать обработчик команды меню (свойство COMMAND) и/или обработчик обновления интерфейса (свойство UPDATE_COMMAND_UI). Итак, считаем, что на этом шаге Вы создали заготовки обработчиков сообщений (COMMAND) для команд меню Студент и сообщений обновления пользовательского интерфейса (UPDATE_COMMAND_UI) и присвоили им имена в соответствии с табл. 2. Эти обработчики надо создавать именно для класса представления – CFRMView.
Таблица 2 Команды меню Студент и соответствующие им кнопки
Если сейчас запустить собрать приложение и запустить его на выполнение, то можно заметить, что команды меню Студент стали доступны, как и соответствующие им кнопки панели инструментов. Приведенные в табл. 2 обработчики сообщений обновления пользовательского интерфейса вызываются или в момент простоя — для обновления состояния кнопок панели инструментов, или при вызове меню Студент – для обновления пунктов меню. Например, кнопка, выбирающая первую запись, отключена, если список пуст, а также, если переменная m_position уже указывает на первую запись. Кнопка выбора предыдущей записи отключается в тех же случаях, поэтому она должна использовать тот же обработчик команды обновления пользовательского интерфейса. По этой же причине для кнопок выбора следующей и последней записи надо использовать один и тот же обработчик команды обновления пользовательского интерфейса. «Привязать» один и тот же обработчик UPDATE_COMMAND_UI к разным кнопкам с помощью мастера не удастся, но можно это сделать «вручную». Для этого отредактируйте карту обработки сообщений (message map) в файле «вида» FRMView.cpp (добавления выделены полужирным шрифтом):
BEGIN_MESSAGE_MAP(CFRMView, CFormView) ON_BN_CLICKED(IDC_ENTER, &CFRMView::OnBnClickedEnter) ON_COMMAND(ID_EDIT_CLEAR_ALL, &CFRMView::OnEditClearAll) ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR_ALL, &CFRMView::OnUpdateEditClearAll) ON_COMMAND(ID_STU_FIRST, &CFRMView::OnStuFirst) ON_COMMAND(ID_STU_DEL, &CFRMView::OnStuDel) ON_COMMAND(ID_STU_INS, &CFRMView::OnStuIns) ON_COMMAND(ID_STU_LAST, &CFRMView::OnStuLast) ON_COMMAND(ID_STU_NEXT, &CFRMView::OnStuNext) ON_COMMAND(ID_STU_PREV, &CFRMView::OnStuPrev) ON_UPDATE_COMMAND_UI(ID_STU_FIRST, &CFRMView::OnUpdateStuFirst) ON_UPDATE_COMMAND_UI(ID_STU_LAST, &CFRMView::OnUpdateStuLast) ON_UPDATE_COMMAND_UI(ID_STU_DEL, &CFRMView::OnUpdateStuDel) ON_UPDATE_COMMAND_UI(ID_STU_PREV, &CFRMView::OnUpdateStuFirst) ON_UPDATE_COMMAND_UI(ID_STU_NEXT, &CFRMView::OnUpdateStuLast) END_MESSAGE_MAP()
Заметьте, что обработчика UPDATE_COMMAND_UI для команды вставки новой записи нет, так он не нужен. Проверьте отсутствие ошибок компиляции и сборки, а также работоспособность приложения на этом этапе его разработки.
Шаг 5. Удаление обработчика команды Clear All меню Edit из класса вида. Удалите этот обработчик вместе с обработчиком UPDATE_COMMAND_UI, так как эту команду мы будем теперь обрабатывать в классе документа. Удаление выполняется по аналогии с генерацией. Заметьте, что мастер не удаляет соответствующие строки из файлов FRMView.h и FRMView.cpp, а просто комментирует их. Можно их и совсем удалить. Шаг 6. Доработка класса документа CFRMDoc. В настоящее время в файле FRMDoc.h в теле класса CFRMDoc содержится описание члена класса CStudent: public: CStudent m_student;
Найдите его и удалите, так как теперь мы будем обрабатывать список студентов и его надо включить в класс. Добавьте такое описание члена класса документа (например, на место удаленного описания): private: CStudentList m_studentList;
Так как в соответствии с хорошим стилем программирования член-данное m_studentList мы сделали закрытым, надо добавить функцию доступа к нему (в тело класса CFRMDoc): // Attributes public: CStudentList* GetList() { return &m_studentList; }
Подставляемая функция GetList помогает изолировать представление от документа. Класс документа зависит от типа объектов в списке, в данном случае — от объектов класса CStudent. Однако базовый класс «вид», чтобы получить указатель на список, не зная имени его объекта, может вызвать функцию-член GetList().
Теперь изменим реализацию конструктора класса (см. файл FRMDoc.cpp) на такую:
Вызов функции afxDump.SetDepth(1) обеспечивает вывод отладочной информации по отдельным элементам списка, а не только по списку целиком. Добавим также отладочный вывод в метод OnNewDocument(): BOOL CFRMDoc::OnNewDocument() { TRACE("Вход в CFRMDoc::OnNewDocument()\n"); if (!CDocument::OnNewDocument()) return FALSE; return TRUE; }
и отредактируем функцию Dump() для вывода элементов списка: void CFRMDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); dc << "\n" << m_studentList << "\n"; } Попробуйте собрать приложение – Вы должны увидеть сообщения об ошибках компиляции (класса CFRMVIew) связанные с тем, что мы удалили член-данное m_student. Просто удалите все строки программы, где используется m_student. Теперь приложение должно собираться. Запустите его на выполнение, посмотрите на сообщения в окне Debug; пощекотите мышиным хвостиком кнопки и понаблюдайте, что при этом выводится в окно Debug. Закройте программу – в окне Debug Вы должны увидеть сообщение вида «a CObList at $00359004 with 0 elements» - список пока пуст.
Шаг 7. Добавление обработчиков сообщений в класс документа CFRMDoc. Добавьте обработчик команды Clear All меню Edit в класс документа (а не вида!) и обработчик сообщения обновления пользовательского интерфейса для этой же команды и наполните их таким содержанием:
Функцию базового класса CDocument::DeleteContents() надо перекрыть (вкладка overrides в окне Properties) и наполнить таким кодом:
Заготовку перекрытой функции можно сгенерировать с помощью мастера, выбрав класс CFRMDoc в окне ClassView и вкладку Overrides в окне Properties. Обратите внимание на то, как мастер объявил эту функцию в файле FRMDoc.h: private: CStudentList m_studentList; afx_msg void OnEditClearAll(); afx_msg void OnUpdateEditClearAll(CCmdUI *pCmdUI); virtual void DeleteContents(); DeleteContents – переопределенная виртуальная функция, вызываемая другими функциями класса «документ» и каркасом приложений. Ее задача — извлекать из списка указатели на объекты CStudent и удалять эти объекты. DeleteContents попутно, т.е. даром, выводит информацию о списке студентов. На этом этапе мы имеем работающее, но пока бесполезное приложение, не так ли?
Шаг 8. Первая доработка класса вида CFRMVIew. Добавьте в тело этого класса (файл FRMVIew.h) такие член-данные (изменения выделены полужирным шрифтом): class CFRMView: public CFormView { protected: POSITION m_position; // текущая позиция в списке документа CStudentList* m_pList; // указатель на список, скопированный из документа
Член-данное m_position будет выполнять роль своего рода курсора для набора объектов в документе. Он ссылается на отображаемый в данный момент объект CStudent окне вида. Член m_pList просто обеспечивает быстрый доступ к списку студентов в документе. Его надо инициализировать в конструкторе класса: CFRMView::CFRMView(): CFormView(CFRMView::IDD) , m_strName(_T("")) , m_nGrade(0) { m_pList=NULL; }
Вы помните, что в классе CFRMView у нас по-прежнему объявлены переменные-члены CString m_strName; int m_nGrade;
ассоциированные с элементами ввода фамилии и отметки студента (см. файл FRMVIew.h). Кроме того, в этом же классе у нас все еще имеется функция OnBnClickedEnter(), являющаяся обработчиком нажатия кнопки «Очистить» и которая теперь должна выполнять очистку элементов ввода фамилии и отметки студента. Можно, конечно, изменить имя OnBnClickedEnter() на, например, OnClear(), но можно этого и не делать. Переменную m_pList надо инициализировать при запуске приложения, что лучше всего сделать в виртуальной функции CFRMView::OnInitialUpdate(). Отредактируйте ее следующим образом:
Мы убрали вызов UpdateControlsFromDoc() из OnInitialUpdate() по причине ненадобности. Теперь полезно написать функции, которые должны извлекать объекты CStudent из списка (GetEntry), вставлять новый объект в список (InsertEntry) и очищать (ClearEntry) управляющие элементы ввода фамилии и отметки в окне вида. Вот текст этих функций (их реализацию надо поместить в файл CFRMView.cpp):
Прототипы этих функций надо поместить в тело класса вида (файл CFRMView.h): protected: virtual void ClearEntry(); virtual void InsertEntry(POSITION position); virtual void GetEntry(POSITION position); Функция GotoDlgCtrl() просто переводит фокус на указанный в качестве параметра управляющий элемент, в данном случае это поле ввода фамилии. Если убрать ее вызов, то фокус останется на кнопке Очистить. Чтобы хоть как-то тестировать программу на этом этапе, добавим вызов ClearEntry() в обработчик нажатия кнопки Очистить: void CFRMView::OnBnClickedEnter() { TRACE("Вход в CFRMView::OnBnClickedEnter()\n"); ClearEntry(); }
Если теперь собрать приложение и запустить его на выполнение, то можно проверить, что нажатие кнопки Очистить действительно приводит к очистке полей ввода фамилии и отметки. Ура? Шаг 9. Вторая доработка класса вида CFRMVIew. Теперь осталось наполнить кодом обработчики нажатий кнопок манипуляций со списком студентов. Заготовки этих обработчиков у нас уже есть. Кроме того, Вам надо сгенерировать перекрытую функцию CFRMView::OnUpdate (вкладка Overrides в окне Properties) и добавить в нее свой код. Не забудьте снять комментарии с описания формальных параметров функции CFRMView::OnUpdate. void CFRMView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { // вызывается OnInitialUpdate и UpdateAllViews TRACE("Вход в CFRMView::OnUpdate\n"); m_position = m_pList->GetHeadPosition(); GetEntry(m_position); /*извлечение из списка начальных данных для просмотра */ }
Виртуальная функция OnUpdate вызывается как функцией OnInitialUpdate(), так и функцией CDocument::UpdateAllViews(). Она устанавливает текущее положение на начало списка и отображает его первый элемент. Пока функция UpdateAllViews вызывается только по команде Clear All (меню Edit), но далее мы будем вызывать ее и из других точек программы. В приложении с несколькими представлениями данных в ответ на обновление документа из другого окна представления может понадобиться иная стратегия установки переменной m_position в классе CFRMView. Отредактируйте, наконец, обработчики сообщений:
Дата добавления: 2014-12-26; Просмотров: 440; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |