Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов
Шрифт:
Интервал:
Закладка:
LoadStdProfileSettings();
// Создаем шаблон документа
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MULTITYPE, RUNTIME_CLASS(CMultiDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMultiView));
// Регистрируем шаблон документа
AddDocTemplate(pDocTemplate);
// Создаем главное окно приложения (MDI Frame window)
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE;
m_pMainWnd = pMainFrame;
// Выполняем стандартную обработку командной строки
// приложения
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Обрабатываем командную строку приложения
if (!ProcessShellCommand(cmdInfo)) return FALSE;
// Отображаем окно
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
return TRUE;
}
В начале InitInstance вызываются методы Enable3dControls и LoadStdProfileSettings. Они уже были описаны в предыдущем томе серии “Библиотека системного программиста”, посвященном MFC, поэтому мы не станем на них останавливаться и перейдем к рассмотрению шаблонов документа приложения.
Затем создается указатель pDocTemplate на объекты класса шаблона документов. Для однооконных приложений это класс CSingleDocTemplate, а для многооконных – CMultiDocTemplate. Создается новый объект класса и указатель на него записывается в переменную pDocTemplate. Для создания шаблона документа используется оператор new.
Конструктору класса CMultiDocTemplate передаются четыре параметра:
CMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
Первый параметр nIDResource определяет идентификатор ресурсов, используемых совместно с типом документов, управляемых шаблоном. К таким ресурсам относятся меню, пиктограмма, строковый ресурс, таблица акселераторов. Для приложения Multi в этом параметре указан идентификатор IDR_MULTITYPE.
Остальные три параметра pDocClass, pFrameClass и pViewClass содержат указатели на объекты класса CRuntimeClass, полученные с помощью макрокоманд RUNTIME_CLASS из классов документа CMultiDoc, дочернего окна MDI CChildFrame и окна просмотра CMultiView. Таким образом, шаблон документа объединяет всю информацию, относящуюся к данному типу документов.
Созданный шаблон документов заносится в список шаблонов, с которыми работает приложение. Для этого указатель на созданный шаблон документа передается методу AddDocTemplate из класса CWinApp. Указатель на шаблон документов передается через параметр pTemplate:
void AddDocTemplate(CDocTemplate* pTemplate);
Указатель pTemplate должен указывать на объект класса CDocTemplate, однако мы передаем через него указатель на объект класса CMultiDocTemplate. Это допустимо, так как класс CDocTemplate является базовым классом для CMultiDocTemplate.
Если вы разрабатываете приложение, основанное на однооконном или многооконном интерфейсе, объект главного класса приложения управляет одним или несколькими объектами класса шаблона документа. Они, в свою очередь, управляют созданием документов. Один шаблон используется для всех документов данного типа.
После создания шаблона документа создается главное окно MDI (главное окно приложения).
Для создания главного окна приложения мы формируем объект класса CMainFrame и записываем указатель на него в pMainFrame. Класс CMainFrame определен в нашем приложении. Мы расскажем о нем немного позже:
// Создаем главное окно MDI (главное окно приложения)
CMainFrame* pMainFrame = new CMainFrame;
Затем для только что созданного объекта вызывается метод LoadFrame класса CFrameWnd. Он создает окно, загружает ресурсы, указанные первым параметром, и связывает их с объектом класса CMainFrame. Параметр метода LoadFrame определяет меню, пиктограмму, таблицу акселераторов и таблицу строк главного окна приложения:
if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE;
Указатель на главное окно приложения, которым является главное окно MDI, записывается в элемент данных m_pMainWnd главного класса приложения. Элемент данных m_pMainWnd, определенн в классе CWinThread. Когда окно, представленное указателем m_pMainWnd закрывается, приложение автоматически будет завершено (в случае если приложение включает в себя несколько задач, завершается только соответствующая задача):
m_pMainWnd = pMainFrame;
Метод LoadFrame не отображает главное окно приложения на экране. Для этого надо вызвать методы ShowWindow и UpdateWindow:
// Отображаем главное окно приложения
pMainFrame->ShowWindow(m_nCmdShow);
// Обновляем содержимое окна
pMainFrame->UpdateWindow();
В заключение метода InitInstance обрабатывается командная строка приложения. Для этого создается объект cmdInfo класса CCommandLineInfo и для него вызываются методы ParseCommandLine и ProcessShellCommand:
// Просматриваем командную строку приложения в поиске
// стандартных команд и обрабатываем их
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Распределяем команды, указанные в командной строке
// приложения
if (!ProcessShellCommand(cmdInfo)) return FALSE;
Таблица сообщенийКласс CMultiApp может получать сообщения и имеет таблицу сообщений. Таблицу сообщений класса CMultiApp расположена в файле Multi.cpp. Она содержит четыре макрокоманды для обработки командных сообщений от меню приложения:
//////////////////////////////////////////////////////////////
// Таблица сообщений класса CMultiApp
BEGIN_MESSAGE_MAP(CMultiApp, CWinApp)
//{{AFX_MSG_MAP(CMultiApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
//}}AFX_MSG_MAP
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
Только для одного командного сообщения, имеющего идентификатор ID_APP_ABOUT, вызывается метод обработчик OnAppAbout, определенный в классе CMultiApp. Остальные три командных сообщения ID_FILE_NEW, ID_FILE_OPEN и ID_FILE_PRINT_SETUP передаются для обработки методам класса CWinApp, который является базовым классом для CMultiApp.
Метод-обработчик OnAppAbout вызывается объектом главного класса приложения, когда пользователь выбирает из меню Help строку About. OnAppAbout создает объект класса CAboutDlg, представляющий модальную диалоговую панель About и вызывает для него метод DoModal, отображающий панель на экране (рис. 1.9):
void CMultiApp::OnAppAbout() {
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
Рис. 1.9. Окно Project Workspace, класс CMainFrame
Класс главного окна приложенияВнутри главного окна приложения отображаются панели управления и состояния, дочерние MDI окна, используемые для просмотра документов. Для управления главным окном приложения используется класс CMainFrame, определенный в файле MainFrm.h.
Вы можете изучить класс CMDIFrameWnd, просмотрев его структуру в окне Project Workspace, на странице ClassView (рис. 1.10). Выполните двойной щелчок левой кнопкой мыши по названию класса или по названию интересующего вас метода, и соответствующий программный код загрузится в окно редактора Microsoft Visual C++.
Рис. 1.10. Окно Project Workspace, класс CMainFrame
Ниже мы привели определение класса CMainFrame:
class CMainFrame : public CMDIFrameWnd {
DECLARE_DYNAMIC(CMainFrame)
public:
CMainFrame();
// Attributes
public:
// Operations
public:
// Overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Класс главного окна многооконного приложения CMainFrame практически полностью соответствует классу главного окна однооконного приложения. Даже названия этих классов одинаковы. Однако обратите внимание, что класс CMainFrame наследуется от базового класса CMDIFrameWnd, а не от CFrameWnd, как это было для однооконного приложения.
Конструктор и деструктор класса CMainFrameНиже представлены конструктор и деструктор класса CMainFrame. Изначально они не содержат программного кода и представляют собой простые заготовки. Вы можете использовать их для дополнительной инициализации объекта класса:
// Конструктор класса CMainFrame
CMainFrame::CMainFrame() {
// TODO:
}
// Деструктор класса CMainFrame
CMainFrame::~CMainFrame() {}
Таблица сообщений класса CMainFrameТаблица сообщений класса CMainFrame содержит только одну макрокоманду ON_WM_CREATE, которая устанавливает для обработки сообщения WM_CREATE метод OnCreate. Сообщения WM_CREATE приходит во время создания главного окна приложения.