Compartilhar via


Adicionando várias exibições a um único documento

Em um aplicativo SDI (interface de documento único) criado com a Biblioteca de Classe do Microsoft Foundation (MFC), cada tipo de documento é associado a um único tipo de exibição. Em alguns casos, é desejável ter a capacidade de alternar a exibição atual de um documento com uma nova exibição.

Dica

Para obter procedimentos adicionais sobre como implementar várias exibições para um único documento, consulte CDocument::AddView e o exemplo COLLECT MFC.

Você pode implementar essa funcionalidade adicionando uma nova CViewclasse derivada e um código adicional para alternar os modos de exibição dinamicamente para um aplicativo MFC existente.

As etapas são as seguintes:

O restante deste tópico pressupõe o seguinte:

  • O nome do CWinAppobjeto derivado é CMyWinApp, e CMyWinApp é declarado e definido em MYWINAPP. H e MYWINAPP. CPP.

  • CNewView é o nome do novo CViewobjeto derivado e CNewView é declarado e definido em NEWVIEW. H e NEWVIEW. CPP.

Modificar a classe de aplicativo existente

Para que o aplicativo alterne entre exibições, você precisa modificar a classe de aplicativo adicionando variáveis de membro para armazenar as exibições e um método para alterná-las.

Adicione o código a seguir à declaração de CMyWinApp em MYWINAPP.H:

CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();

As novas variáveis de membro m_pOldView e m_pNewView apontam para a exibição atual e a recém-criada. O novo método (SwitchView) alterna as exibições quando solicitado pelo usuário. O corpo do método é discutido posteriormente neste tópico em Implementar a Função de Comutação.

A última modificação na classe de aplicativo requer a inclusão de um novo arquivo de cabeçalho que define uma mensagem do Windows (WM_INITIALUPDATE) usada na função de comutação.

Insira a linha a seguir na seção de inclusão de MYWINAPP. CPP:

#include <AFXPRIV.H>

Salve suas alterações e continue para a próxima etapa.

Criar e modificar a nova classe de exibição

A criação da nova classe de exibição é facilitada usando o comando Nova Classe disponível no Modo de Exibição de Classe. O único requisito para essa classe é que ela deriva de CView. Adicione essa nova classe ao aplicativo. Para obter informações específicas sobre como adicionar uma nova classe ao projeto, consulte Adicionando uma classe.

Depois de adicionar a classe ao projeto, você precisará alterar a acessibilidade de alguns membros de classe de exibição.

Modifique NEWVIEW.H alterando o especificador de acesso de protected para public para o construtor e o destruidor. Isso permite que a classe seja criada e destruída dinamicamente e modifique a aparência da exibição antes de ficar visível.

Salve suas alterações e continue para a próxima etapa.

Criar e anexar a nova visualização

Para criar e anexar o novo modo de exibição, você precisa modificar a InitInstance função da classe de aplicativo. A modificação adiciona um novo código que cria um novo objeto de exibição e, em seguida, inicializa ambos m_pOldView e m_pNewView com os dois objetos de exibição existentes.

Como a nova exibição é criada dentro da InitInstance função, as exibições novas e existentes persistem durante o tempo de vida do aplicativo. No entanto, o aplicativo poderia facilmente criar o novo modo de exibição dinamicamente.

Insira este código após a chamada para 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);

Salve suas alterações e continue para a próxima etapa.

Implementar a função de comutação

Na etapa anterior, você adicionou código que criou e inicializou um novo objeto de exibição. A última parte principal é implementar o método de alternância SwitchView.

No final do arquivo de implementação da classe de aplicativo (MYWINAPP). CPP), adicione a seguinte definição de método:

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;
}

Salve suas alterações e continue para a próxima etapa.

Adicionar suporte para alternar o modo de exibição

A etapa final envolve a adição de código que chama o SwitchView método quando o aplicativo precisa alternar entre exibições. Isso pode ser feito de várias maneiras: adicionando um novo item de menu para o usuário escolher ou alternar as exibições internamente quando determinadas condições forem atendidas.

Para obter mais informações sobre como adicionar novos itens de menu e funções de manipulador de comandos, consulte Manipuladores para Comandos e Notificações de Controle.

Consulte também

Arquitetura de documento/exibição