Добавление нескольких представлений в один документ
В приложении (SDI) однодокументного интерфейса, созданном с библиотекой Microsoft Foundation Class (MFC), каждый тип документа связан с одним типом представления. В некоторых случаях желательно иметь возможность переключаться текущее представление документа с новым представлением.
Совет
Для дополнительных процедур в реализации нескольких представлений для одного документа см. в разделе CDocument::AddView и в примере MFC СОБЕРИТЕ.
Можно реализовать эту функцию, добавив новое CView- производный класс и дополнительный код для переключения представлений динамически в существующее приложение MFC.
Ниже приводятся этапы выполнения сценария.
Измените класс существующих приложений
Создание и изменение новый класс представления
Создайте новое представление и вложите
Реализуйте функцию ключа
Добавьте поддержку переключать представления
Оставшаяся часть этого раздела предполагается следующее:
Имя CWinApp- производного объекта CMyWinApp и CMyWinApp объявляется и определяется в MYWINAPP.H и MYWINAPP.CPP.
CNewView имя нового CView- производного объекта и CNewView объявляются и определены в NEWVIEW.H и NEWVIEW.CPP.
Измените класс существующих приложений
Для приложения переключаться между представлениями необходимо изменить класс приложения путем добавления переменные-члены для хранения представления и метод для переключения их.
Добавьте следующий код к объявлению CMyWinApp в MYWINAPP.H:
CView* m_pOldView;
CView* m_pNewView;
CView* SwitchView( );
Новые переменные-члены, m_pOldView и m_pNewView выберите текущему представлению и вновь созданный объект одно. Новый метод (SwitchView) переключает представления исключение пользователем. Тело метода см. далее в этом разделе в Реализуйте функцию ключа.
Последнее изменение в класс приложения требуется включая новый файл заголовка, который определяет сообщение Windows (WM_INITIALUPDATE), которое используется в функции переключателя.
Вставьте следующую линии в разделе включение MYWINAPP.CPP:
#include <AFXPRIV.H>
Сохраните изменения и продолжить к следующему шагу.
Создание и изменение новый класс представления
Создать новый класс представления является простым с помощью команды Новый класс доступной из представления классов. Единственное требование для этого класса, он является производным от CView. Добавьте этот новый класс к приложению. Для получения сведений о добавлении новый класс к проекту см. в разделе Добавление класса.
После добавления в проект класс, необходимо изменить специальные возможности некоторых членов класса представления.
Измените NEWVIEW.H путем изменения описатель доступа с protected в public для конструктора и деструктора. Это позволяет класс, который должен быть создан и уничтоженному динамически и для изменения внешнего вида представления до того, как он отображается.
Сохраните изменения и продолжить к следующему шагу.
Создайте новое представление и вложите
Для создания и вложить нового представления необходимо изменить функции InitInstance класса приложения. Изменение добавляется новый код, который создает новый объект представления и затем инициализирует и m_pOldView и 2 m_pNewView с существующими объектами представления.
Поскольку новое представление создается внутри функции InitInstance и новая и существующие представления сохраняются во время существования приложения. Однако приложение может легко присвоить новое представление динамически.
Вставьте этот код после вызова метода ProcessShellCommand:
CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView*) new CNewView;
if (NULL == m_pNewView)
return FALSE;
CDocument* pCurrentDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
// Initialize a CCreateContext to point to the active document.
// With this context, the new view is added to the document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = pCurrentDoc;
// The ID of the initial active view is AFX_IDW_PANE_FIRST.
// Incrementing this value by one for additional views works
// in the standard document/view case but the technique cannot
// be extended for the CSplitterWnd case.
UINT viewID = AFX_IDW_PANE_FIRST + 1;
CRect rect(0, 0, 0, 0); // Gets resized later.
// Create the new view. In this example, the view persists for
// the life of the application. The application automatically
// deletes the view when the application is closed.
m_pNewView->Create(NULL, _T("AnyWindowName"), WS_CHILD, rect, m_pMainWnd, viewID, &newContext);
// When a document template creates a view, the WM_INITIALUPDATE
// message is sent automatically. However, this code must
// explicitly send the message, as follows.
m_pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);
Сохраните изменения и продолжить к следующему шагу.
Реализуйте функцию ключа
В предыдущем шаге будет добавлен код, который создал и инициализировал новый объект представления. Последний элемент реализовать метод главного ключа, SwitchView.
В конце файла реализации класса приложения (MYWINAPP.CPP) добавьте определение следующего приема:
CView* CMyWinApp::SwitchView( )
{
CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
CView* pNewView = NULL;
if(pActiveView == m_pOldView)
pNewView = m_pNewView;
else
pNewView = m_pOldView;
// Exchange view window IDs so RecalcLayout() works.
#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
#endif
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd*) m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}
Сохраните изменения и продолжить к следующему шагу.
Добавьте поддержку переключать представления
Последний шаг позволяет добавить код, который вызывает метод SwitchView, когда приложению требуется переключаться между представлениями. Это можно сделать несколькими способами: или добавление нового пункта меню для пользователя, чтобы выбрать или переключение представлений внутри кода при некоторых условиях будут выполнены.
Дополнительные сведения о добавлении новые пункты меню и функции обработчиков команд см. в разделе Обработчики для команд и уведомлений элемента управления.