Шаг 26 - Пункт меню новый документ как в AppWizard

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

Работаем с текущим проектом. Только в нашем пункте меню File нужно создать пункт меню New с идентификатором ID_FILE_NEW. Хотя идентификатор может быть любой, но мы договорились сделать как в волшебнике.

26_1.gif (2139 b)

Создаем код

Добавляем таблицу откликов в класс приложения.

class CStep2App : public CWinApp	        // класс приложения
{
public:
CStep2App();
virtual BOOL InitInstance();
private:
DECLARE_MESSAGE_MAP() // таблица откликов для класса приложения
};

И её реализация.

BEGIN_MESSAGE_MAP(CStep2App, CWinApp)
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) // пункт меню New
END_MESSAGE_MAP()

Добавляем функцию новый документ в класс документа.

class CMyDoc : public CDocument	 // класс документа
{
protected:
CMyDoc();
CString csDate; // здесь будем хранить
virtual BOOL OnNewDocument(); // будет вызываться при выборе меню New
DECLARE_DYNCREATE(CMyDoc)
public:
CString GetDate(); // получить данные
void SetString(CString s); // установить строку
void OnAbout(); // реакция на выбор меню
private:
DECLARE_MESSAGE_MAP(); // таблица откликов
};

И реализация.

BOOL  CMyDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument()) // Если не удалось создать документ
return FALSE; // Вернуть ошибку
csDate="Hello View - Doc"; // Изменить данные в документе
return TRUE;
}

Изменить конструктор документа.

CMyDoc::CMyDoc()
{
TRACE("CMyDoc::CMyDoc()\n"); // вывести в окно отладки
}

Вот так приложение должно работать.

26_2.gif (19539 b)

Описание

Описание я начну с механизма реализации функции новый документ. В MFC заложены механизмы автоматизации пункта меню New. Конструктор документа вызывается только один раз при создании приложения. Больше он не вызывается. Это вы можете проверить, запустив приложение в режиме отладки (F5 Go).

26_3.gif (3006 b)

Запускайте, получите сообщение от конструктора. Выбирайте пункт меню New и ничего. В окне отладки будет только одна надпись о создании объекта документа.

Loaded 'C:\WINDOWS\SYSTEM\MFC42LOC.DLL', no matching symbolic information found.
Warning: no document names in string for template #101.
Warning: no document names in string for template #101.
CMyDoc::CMyDoc()
Loaded 'C:\WINDOWS\SYSTEM\INDICDLL.DLL', no matching symbolic information found.
The thread 0xFFF89A49 has exited with code 0 (0x0).
The program 'D:\VС\step26\Debug\step26.exe' has exited with code 0 (0x0).

Так вот, для создания нового документа используется виртуальная функция OnNewDocument. Именно поэтому я убрал из конструктора определение строки csDate. Все данные должны определяться в OnNewDocument.

Ну, теперь смотрим сверху. Первое добавили таблицу отклика в класс приложения. В этом классе CWinApp есть механизм вызова NewDocument. Вот мы его вызываем обращаясь к функции CWinApp::OnFileNew. Далее мы создаем функцию OnNewDocument для класса CDocument и её реализацию. Вызываем функцию отца для нормальной работы. Устанавливаем данные и говорим, новый документ создан удачно return TRUE;.

Запускайте. А теперь ходовые испытания. Первое. Вызываем меню About для изменения данных, если вы нечего не меняли, то должен появиться надпись Первые шаги. А теперь вызовем New, и в видах меняются надписи. Они вернутся к начальному состоянию.

Вот так, работает. Это классно. Классно потому что понятно. И если вы будете, а вы будете пользоваться волшебником обязательно, то я надеюсь поймете в чем дело.

Шпаргалка

Создать пункт меню с идентификатором.

ID_FILE_NEW

Создать реакцию на него в классе приложения.

BEGIN_MESSAGE_MAP(CStep2App, CWinApp)
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) // пункт меню New
END_MESSAGE_MAP()

Создать функцию новый документ.

BOOL  CMyDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument()) // Если не удалось создать документ
return FALSE; // Вернуть ошибку
csDate="Hello View - Doc"; // Изменить данные в документе
return TRUE;
}

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