Click here to Skip to main content
Click here to Skip to main content

Replacing a view in an in-place activated server

, 28 Dec 1999
Rate this:
Please Sign up or sign in to vote.
Replacing a view in an in-place activated server.

To fully understand what follows, some previous knowledge is required, namely how MFC creates documents, frame windows and views using document templates and how their relationship is maintained in the program. A previous article showing how to replace views in non-OLE applications is a recommended reading.

First of all, let's understand how the framework creates OLE frames. When a server object is inserted in a container, a document, a frame window and a view contained within it (or multiple views, if it is a splitter) are first constructed, following common document-template procedures. After that, in response to the OLEIVERB_SHOW OLE verb, the COleServerDoc::ActivateInPlace function is called. If there is no previous OLE frame (i.e. it is the first time it will be activated), the OLE frame is created, calling the COleServerDoc::CreateInPlaceFrame function. Here, not only the OLE frame is created (using the CDocTemplate::CreateOleFrame function), but also the view in the previously constructed frame window is "connected" to the newly created OLE frame. If the original frame was a splitter, then the view in the first pane is used. The "connection" process consists on changing the view's parent window to the new frame. It is performed calling the COleServerDoc::ConnectView function. The active view on the original frame window is kept (using the m_pActiveView member), because some controls continue to send notification messages to their original parent window. These notification messages should be handled in the original frame window. Once the OLE frame is created and a view is "connected" to it, then it is activated.

Now, if we want to replace a view in an OLE frame, we have to replace it in 2 frame windows: the OLE frame and the original frame. The current active view should be destroyed, a new view should be created within the original frame and be later connected to the OLE frame. The active views should be set to NULL first, so no Windows message could be sent by the framework to a non-valid view stored in the m_pActiveView member of the frame windows.

To perform this, we need a method in our document class, which should receive the new view type as a parameter and return a success flag. The advantage of having this method in the document class becomes obvious when there are several document types each of which can have different view types. Note that the document should be a COleServerDoc descendant. This is how it is done:

BOOL CMyDoc::InPlaceSwitchToView ( CRuntimeClass *pNewViewClass )
{
   // The original parent window is saved in m_pOrigParent.
   CFrameWnd* pFrame = (CFrameWnd *)m_pOrigParent;

   // Get the active view.
   View* pOldActiveView = m_pInPlaceFrame->GetActiveView();

   // If we're already displaying this kind of view, no need to go further.
   if (pOldActiveView->IsKindOf(pNewViewClass))
      return TRUE;

   // No currently active views in either frame
   pFrame->SetActiveView(NULL);
   m_pInPlaceFrame->SetActiveView(NULL);

   // Set flag so that document will not be deleted when view is destroyed.
   BOOL bAutoDelete = m_bAutoDelete;
   m_bAutoDelete = FALSE;

   // Delete existing view
   pOldActiveView->DestroyWindow();

   // restore flag
   m_bAutoDelete = bAutoDelete;

   // Create new view.
   CView* pNewView = (CView *)pNewViewClass->CreateObject();
   if (pNewView == NULL)
   {
      TRACE1("Warning: Dynamic create of view type %Fs failed\n", 
                                pNewViewClass->m_lpszClassName);
      return FALSE;
   }

   // Draw new view.
   CCreateContext context;
   context.m_pNewViewClass = pNewViewClass;
   context.m_pCurrentDoc = this;
   context.m_pNewDocTemplate = NULL;
   context.m_pLastView = NULL;
   context.m_pCurrentFrame = pFrame;
   if (!pNewView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), 
      pFrame, AFX_IDW_PANE_FIRST, &context))
   {
      TRACE0("Warning: couldn't create view for frame\n");
      delete pNewView;
      return FALSE;
   }

   // Keep the view active in the original frame
   pFrame->SetActiveView(pNewView);

   // Connect the view to the OLE frame
   ConnectView(m_pInPlaceFrame, pNewView);
   pNewView->ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME);
   pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);

   // WM_INITIALUPDATE is defined in afxpriv.h
   pNewView->UpdateWindow();

   return TRUE;
}

Now that we have a method in our document class that will replace the current view in an OLE frame, let's use it. The new view type should be decided (in response to a menu selection, for instance), and the function must be called as follows:

   CRuntimeClass* pNewViewClass = RUNTIME_CLASS(CMyView);
   if (!InPlaceSwitchToView(pNewViewClass))
      // failed
   else
      // succeeded

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

No Biography provided

Comments and Discussions

 
QuestionHow to hide/Show ole server object from container object Pinmembervimala27-Apr-03 22:56 
I am developing an Ole container application using MFC just like Microsoft office binder, it should load the different server objects like(word, Excel. etc..). This container application should have a interface like Office Binder with Splitter window. The left pane would contain the icons of all independent ole server objects and the right pane would display the interface of the Server objects that is currently active.
 
So that server UI will merge into container UI, once the container loads the server object (just like Office Binder).
 
What i really want to know is how Office Binder and its server objects communicate with each other when office binder hides/unhides its server objects?
 
If i click the hide/unhide the menu items of Server object within the container item, the container should hide the server object from its view and also it should able to show it again if i unhide the server object.
 
I want to know how the container and server communicates with each other.
 
Can anyone pls help me out.
 

 

GeneralMore than just a nice view PinmemberKristian Nilssen6-May-01 5:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 29 Dec 1999
Article Copyright 1999 by Jorge Lodos
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid