Шаг 21 - Минимальный проект документ-вид

Создание проекта

Лучше создать новый проект Win32 с именем step21. В шаге 1 мы так делали. Создали проект с нуля. Не забудьте подключить использование MFC. Итак, step21.cpp у нас есть. AppWizard создает код, который интенсивно обращается к ресурсам. Обращение к ним происходит на основе имен. И если мы его эмулируем, то должны пользоваться теми же именами.

Теперь нам нужно добавить файл ресурсов с именем step21.rc. Смотрите шаг 6, если забыли. Сразу после создания файла ресурсов в папочке проекта появиться resource.h. Включите его через Add File to Project в наш проект.

После всех этих магических действий три файла должны быть у нас в проекте.

21_1.gif (1855 b)

В ресурсах нужно создать меню с идентификатором IDR_MAINFRAME. Именно с этим именем так как классы MFC будут обращаться к этому ресурсу меню, именно к этому.

21_2.gif (1768 b)

Еще нам нужен строковый ресурс AFX_IDS_UNTITLED. Если забыли, как добавлять смотрите Шаг 17.

21_3.gif (3486 b)

Этот ресурс используется для задания имени приложения в левом верхнем углу. Если его не будет, то при выполнении вы получите сообщение об ошибке. В реализации MFC есть код.

void CSingleDocTemplate::SetDefaultTitle(CDocument* pDocument)
{
CString strDocName;
if (!GetDocString(strDocName, CDocTemplate::docName) ||
strDocName.IsEmpty())
{
VERIFY(strDocName.LoadString(AFX_IDS_UNTITLED)); // Прочитать строку из ресурсов, успешность чтения проверить
}
pDocument->SetTitle(strDocName);
}

Это проверка установки имени документа по умолчанию на основе строкового ресурса AFX_IDS_UNTITLED.

При создании рамки окна проверяется наличие ресурса с именем IDR_MAINFRAME.

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)
{
if (pDoc != NULL)
ASSERT_VALID(pDoc);
ASSERT(m_nIDResource != 0);// Здесь передается число и
//если этого ресурса нет то ошибка
.............
}

Создаем код

#include "afxwin.h"	// это для MFC 
#include "resource.h" // идентификаторы ресурсов
class CMyView : public CView // класс просмотра
{
protected:
CMyView();
DECLARE_DYNCREATE(CMyView) // Эта функция вызывается для прорисовки вида
public:
virtual void OnDraw(CDC* pDC);
};
void CMyView::OnDraw(CDC* pDC)
{
}
IMPLEMENT_DYNCREATE(CMyView, CView)
CMyView::CMyView()
{
}
class CMainFrame : public CFrameWnd // класс рамки окна
{
protected:
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
public:
};
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
CMainFrame::CMainFrame()
{
}
class CMyDoc : public CDocument // класс документа
{
protected:
CMyDoc();
DECLARE_DYNCREATE(CMyDoc)
public:
};
IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
CMyDoc::CMyDoc()
{
}
class CStep2App : public CWinApp // класс приложения
{
public:
CStep2App();
virtual BOOL InitInstance();
};
BOOL CStep2App::InitInstance()
{
CSingleDocTemplate* pDocTemplate; // новый шаблон
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME, // идентификатор меню
RUNTIME_CLASS(CMyDoc), // документ----|
RUNTIME_CLASS(CMainFrame), // рамка окна--| Документ вид однако.
RUNTIME_CLASS(CMyView)); // просмотр----|
AddDocTemplate(pDocTemplate); // добавить шаблон
CCommandLineInfo cmdInfo; // Класс команд
ParseCommandLine(cmdInfo); // разбор командной строки
if (!ProcessShellCommand(cmdInfo)) // запуск команд на выполнение
return FALSE;
m_pMainWnd->ShowWindow(SW_SHOW); // показать окно
m_pMainWnd->UpdateWindow(); // запустить цикл обработки сообщений
return TRUE;
}
CStep2App::CStep2App()
{
}
CStep2App theApp;

Вот так оно будет выглядеть после запуска.

21_4.gif (1313 b)

Описание

Идеология программирования в MFC заключается в концепции документ вид. Идея здесь в следующем. У вас есть класс, отвечающий за состояние памяти, им пользуются классы отвечающие за отображение. Например, у вас есть данные с координатами деталей, а вы хотите просматривать проекции. Можно создать несколько классов просмотров для проекций.

Для шаблона документа CSingleDocTemplate необходим идентификатор меню и указатели на три класса. Это шаблон для приложений SDI, т.е. с одним документом в окне. Класс просмотра CView. Класс документа CDocument. Класс рамки окна CFrameWnd. Созданный шаблон добавляется функцией AddDocTemplate, а вообще шаблонов может быть несколько!

Следующие функции запускают на выполнение ряд команд. Создать новый документ и т.д. Если что-то непонятно, это не страшно в следующих шагах положение изменится. Я считаю, что лучше раз испытать, чем слушать, и вероятно на примерах понятнее.

Мы с Вами создали код очень близкий к коду AppWizard. И к нему мы будем приближаться. Что будет происходить? При запуске будет сгенерирован шаблон на основе классов рамки, вида, документа. И при запуске процессор команд выполнит функцию Новый документ. После этого окно будет показано.

Шпаргалка

Создать классы документа, вида, рамки окна.

class CMyDoc : public CDocument	 	// класс документа
...........
class CMyView : public CView // класс просмотра
...........
class CMainFrame : public CFrameWnd // класс рамки окна

Создать и добавить шаблон документа.

	pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME, // идентификатор меню
RUNTIME_CLASS(CMyDoc), // документ----|
RUNTIME_CLASS(CMainFrame), // рамка окна--| Документ вид однако.
RUNTIME_CLASS(CMyView)); // просмотр----|
AddDocTemplate(pDocTemplate); // добавить шаблон

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

if (!ProcessShellCommand(cmdInfo))	// запуск команд на выполнение
return FALSE;

Не забыть про ресурсы.

AFX_IDS_UNTITLED
IDR_MAINFRAME

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.