Поделиться через


Добавление нескольких представлений в один документ

В приложении (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, когда приложению требуется переключаться между представлениями. Это можно сделать несколькими способами: или добавление нового пункта меню для пользователя, чтобы выбрать или переключение представлений внутри кода при некоторых условиях будут выполнены.

Дополнительные сведения о добавлении новые пункты меню и функции обработчиков команд см. в разделе Обработчики для команд и уведомлений элемента управления.

См. также

Основные понятия

Архитектура "документ-представление"