Dynamically Create Different Views for SDI Projects





Environment: Any flavour of MFC (Doc/View) including VC6, VC7, and Embedded Visual C++

Sometimes you have an SDI-based project and you do not want to be restricted to a single view (single template). In this article, a piece of code will be presented that will let you change your view of your SDI project dynamically to any other view. In the Windows CE environment, the Visual Embedded Studio does not give you the option of creating MDI projects; this is the perfect alternative for it.

To write this code, I have debugged into the MFC Library and learned few things; I finally took a copy of CSingleDocTemplate::OpenDocumentFile and modified it into a new method called: DynamicOpenDocumentFile(...)

I have Derived a class from CSingleDocTemplate, called CDynamicSingleDocTemplate. It has a new method called DynamicOpenDocumentFile(...) with similar parameters to OpenDocumentFile(...)

CDocument *CDynamicSingleDocTemplate::DynamicOpenDocumentFile
           (LPCTSTR lpszPathName, BOOL bMakeVisible)
{
  // destroy the current view along with its document
  AfxGetMainWnd()->GetDlgItem(AFX_IDW_PANE_FIRST)->DestroyWindow();

  CWinThread* pThread = AfxGetThread();
  pThread->m_pMainWnd = NULL;

  CDocument* pDocument = NULL;
  CFrameWnd* pFrame = NULL;
  BOOL bCreated = FALSE;      // => doc and frame created
  BOOL bWasModified = FALSE;

  if (m_pOnlyDoc != NULL)
  {
    // already have a document -- reinit it
    pDocument = m_pOnlyDoc;
    if (!pDocument->SaveModified())
      return NULL;        // leave the original one

    pFrame = (CFrameWnd*) AfxGetMainWnd();
    ASSERT(pFrame != NULL);
    ASSERT_KINDOF(CFrameWnd, pFrame);
    ASSERT_VALID(pFrame);
  }
  else
  {
    // create a new document
    pDocument = CreateNewDocument();
    ASSERT(pFrame == NULL);     // will be created below
    bCreated = TRUE;
  }

  if (pDocument == NULL)
  {
    AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
    return NULL;
  }
  ASSERT(pDocument == m_pOnlyDoc);

  pFrame = (CFrameWnd*) AfxGetMainWnd();

  // create our view
  CCreateContext context;
  context.m_pCurrentFrame = NULL; // pFrame
  context.m_pCurrentDoc = pDocument;
  context.m_pLastView = NULL;
  context.m_pNewDocTemplate = this;
  context.m_pNewViewClass = m_pViewClass;

  CWnd *pView = pFrame->CreateView(&context);
  if (!pView)
    return NULL;

  if (lpszPathName == NULL)
  {
    // create a new document
    SetDefaultTitle(pDocument);

    // avoid creating temporary compound file when starting
    // up invisible
    if (!bMakeVisible)
      pDocument->m_bEmbedded = TRUE;

    if (!pDocument->OnNewDocument())
    {
      // user has been alerted to what failed in OnNewDocument
      TRACE0("CDocument::OnNewDocument returned FALSE.\n");
      if (bCreated)
        pFrame->DestroyWindow();    // will destroy document
      return NULL;
    }
  }
  else
  {
    CWaitCursor wait;

    // open an existing document
    bWasModified = pDocument->IsModified();
    pDocument->SetModifiedFlag(FALSE);  // not dirty for open

    if (!pDocument->OnOpenDocument(lpszPathName))
    {
      // user has been alerted to what failed in OnOpenDocument
      TRACE0("CDocument::OnOpenDocument returned FALSE.\n");
      if (bCreated)
      {
        pFrame->DestroyWindow();    // will destroy document
      }
      else if (!pDocument->IsModified())
      {
        // original document is untouched
        pDocument->SetModifiedFlag(bWasModified);
      }
      else
      {
        // we corrupted the original document
        SetDefaultTitle(pDocument);

        if (!pDocument->OnNewDocument())
        {
          TRACE0("Error: OnNewDocument failed after trying to open
                 a document - trying to continue.\n");
          // assume we can continue
        }
      }
      return NULL;        // open failed
    }
    pDocument->SetPathName(lpszPathName);
  }

  pThread->m_pMainWnd = pFrame;

  InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
  pFrame->RecalcLayout();

  return pDocument;
}

Downloads

Download demo project - 44 Kb
Download source - 2 Kb


Comments

  • Missing Files

    Posted by Charlie Curtis on 05/06/2004 07:30pm

    This is the method I am looking for, but as stated not all of the files came with the zip download. Would it be possible to get them. Also would be very helpful to others if you could update this link with a new zip file with all document for the project. Anyway would appreciate it if I could get the rest of the files. Thanks Charlie

    Reply
  • missing files

    Posted by Legacy on 09/04/2003 12:00am

    Originally posted by: Kumaru

    hello

    i extracted the project file.
    many files are missing..
    Anydoc.h AnyDoc.cpp etc.
    It is not compiling..
    where those files went?


    Reply
  • DOESN'T WORK WITH CHtmlView ...!!!

    Posted by Legacy on 02/17/2003 12:00am

    Originally posted by: TINKLE

    Hi.,

    When the SDI application view is derived from CHtmlView and try to create CFormView Dynamically , it doesn't work.. it shows some error..!

    Can you tell me ..WHY.???


    Thanks in advance.!

    Warm Regards,
    TINKLE.

    Reply
  • The MSDN Article

    Posted by Legacy on 01/08/2003 12:00am

    Originally posted by: Hayden

    I've also got an app that does this, I started with some microsoft code that can be found in the Visual Studio.Net documentation:

    Go to http://msdn.microsoft.com/ and follow the path ...

    MSDN Library
    .Net Development
    Visual Studio .NET
    Product Documentation
    Visual C++
    Adding Functionality
    Visual C++ Libraries
    MFC
    User Interface
    Document/View Architecture
    Adding Multiple View to a Single Document

    Sorry about the convoluted path, I couldn't work out how to link there.

    This code works well for me, I'm using a CEditView with two 2D and one 3d OpenGL views, great fun.

    Hayden.

    Reply
  • Great job! but .....

    Posted by Legacy on 01/03/2003 12:00am

    Originally posted by: redsword

    i add 2 formview to this project. when i switch the view, the application always get a fatal error and exit.

    Reply
  • Failed for CHtmlView

    Posted by Legacy on 10/23/2002 12:00am

    Originally posted by: Charlie

    Nice job! But It doesn't work if some View class is derived from CHtmlView.

    Reply
  • Great

    Posted by Legacy on 10/11/2002 12:00am

    Originally posted by: Gabriel

    Good job!!!

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date