netlib.narod.ru | < Назад | Оглавление | Далее > |
Далее необходимо изменить инициализирующий код приложения, чтобы обеспечить создание главного окна. Для этого следует отредактировать функцию CStage::InitInstance в файле Stage.cpp. Когда AppWizard строит базовое приложение SDI, он включает в функцию InitInstance код для создания пустого документа, который, в свою очередь, создает главное окно. Поскольку мы удалили код, относящийся к документу, придется строить главное окно самостоятельно. Новая версия функции InitInstance выглядит следующим образом:
BOOL CStageApp::InitInstance() { // Стандартная инициализация // Если вы не используете какие-либо возможности и желаете // сократить размер итогового выполняемого файла, следует // вручную удалить ненужные процедуры инициализации. #ifdef _AFXDLL Enable3dControls(); // Вызывается при использовании MFC //в виде совместной DLL-библиотеки #else Enable3dControlsStatic(); // Вызывается при статической // компоновке MFC #endif LoadStdProfileSettings(); // Загрузить стандартные параметры // из INI-файла (включая MRU) // Загрузить главное обрамленное окно CMainFrame* pFrame = new CMainFrame; if (!pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS VISIBLE)) { return FALSE; } // Сохранить указатель на главное окно m_pMainWnd = pFrame; return TRUE; }
Обратите внимание на два важных действия: вызов функции LoadFrame для загрузки и отображения обрамленного окна и сохранение указателя на него в переменной m_pMainWnd. Указатель сохраняется для того, чтобы классы MFC могли передавать сообщения главному окну приложения, тем самым обеспечивая его правильную работу. Кроме того, необходимо отредактировать файл MainFrm.h и объявить конструктор CMainFrame открытым (public) — по умолчанию он является защищенным (protected). Заодно включите в перечень открытых членов CMainFrame объявление переменной C3dWnd m_wnd3d.
Если на этой стадии откомпилировать и запустить программу, на экране появится главное окно с меню и панелью инструментов. Давайте продолжим работу и закончим программу Stage.cpp, чтобы можно было перейти к созданию трехмерного окна.
В файл Stage.cpp осталось добавить две важные функции: OnIdle и OpenDocumentFile. Первая из них обновляет изображение в окне во время пассивной работы приложения, а вторая необходима для правильного открытия файлов. Воспользуйтесь ClassWizard и включите в класс CStageApp функцию OnIdle, затем отредактируйте ее и приведите к следующему виду:
BOOL CStageApp::OnIdle(LONG lCount) { BOOL bМоrе = CWinApp::OnIdle(lCount); // Получить указатель на главное обрамленное окно CMainFrame* pFrame = (CMainFrame*) m_pMainWnd; if (pFrame) ( // Обновить изображение в трехмерном окне if (pFrame->m_wnd3d.Update(1)) { bМоrе = TRUE; } } return bМоrе; }
Функция OnIdle вызывается во время периода пассивности приложения. Основной принцип ее работы заключается в том, что, когда нашему приложению нечего делать, функция возвращает FALSE, а управление передается другому приложению. Если же оно должно выполнять полезные действия (скажем, приводить в движение трехмерный макет), возвращается значение TRUE, свидетельствующее о необходимости выделения дополнительных квантов пассивного времени. Функция C3dWnd::Update, вызываемая из OnIdle, возвращает значение TRUE в том случае, если отображаемые объекты существуют, и FALSE, если их нет. При таком подходе наше приложение не станет зря требовать дополнительные кванты в том случае, когда ему нечего рисовать.
Вторая функция, которую необходимо включить в Stage.cpp, OpenDocumentFile, предназначена для работы со списком последних открывавшихся файлов в меню. Если добавить в программу код, приведенный в следующем разделе («Модификация главного окна»), но не включить эту функцию, то все будет нормально до тех пор, пока вы не щелкнете на каком-либо имени файла в нижней части меню. В этот момент MFC выдает ASSERT, а ваше приложение останавливается. Жаль, конечно, что работа MFC так тесно привязана к архитектуре «документ/вид», но здесь уж ничего не поделаешь, и нам придется решать проблемы, которые возникли в тот момент, когда мы удалили из своего проекта файлы Doc и View и тем самым вмешались в работу AppWizard. К счастью, сделать это несложно. Все, что необходимо, — переопределить функцию CWinApp::OpenDocumentFile (включите эту функцию в класс CStageApp с помощью ClassWizard):
CDocument* CStageApp::OpenDocumentFile(LPCTSTR lpszFileName) { // Функция вызывается при выборе пользователем // строки из меню последних открывавшихся файлов. // Конкретное возвращаемое значение неважно, оно лишь // должно отличаться от NULL при успешном выполнении // и быть равным NULL при неудаче. CMainFrame* pFrame = (CMainFrame*) m_pMainWnd; if (pFrame) { return (CDocument*) pFrame->OpenFile(lpszFileName); } else { return NULL; } }
Если пользователь щелкнул на имени файла в меню, необходимо передать выбранное имя главному обрамленному окну для обработки, словно пользователь выполнил команду Open в меню File.
Вот и все, что касается общей структуры приложения, однако мы еще не занимались реализацией конкретных функций (таких, как OpenFile), так что при попытке откомпилировать программу вы получите несколько ошибок. Сейчас мы настроим параметры главного окна и добавим в него трехмерные объекты.
netlib.narod.ru | < Назад | Оглавление | Далее > |