Single View in MultiDoc-Application
Sometimes it is useful, to have only one single instance of a document view in a multi-doc application.
The procedure for achieving this is quite straight forwarded. Add a variable of type CMultiDocTemplate* to your application class. Call it m_pTplteOnlyOneView, or give it any name that suits you. Create a class to view that document type. Call it CViewOnlyOneView, or give it any name that suits you. In your initializing code of your application (usually InitInstance) add
m_pTplteOnlyOneView = new CMultiDocTemplate(
IDR_MAIN_MENU, RUNTIME_CLASS(CMultiDocAppForm), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CViewOnlyOneView)); AddDocTemplate(m_pTplteOnlyOneView);
With the application wizard of Visual Studio add a menu command handler for opening this document. Be sure to add that handler in your application class. Also add a handler for the update command function.
Place following code inside the update command handler. Be sure that you use your variable names and not mine.
void CMultiDocApp::OnUpdateOnlyOneView(CCmdUI* pCmdUI)
{ pCmdUI->Enable(TRUE);
if( NULL == m_pTplteOnlyOneView ) pCmdUI->Enable(FALSE);
}
Place following code inside the command handler. Be sure that you use your variable names and not mine.
void CMultiDocApp::OnOnlyOneView()
{ ASSERT_VALID(m_pTplteOnlyOneView);
POSITION Pos = m_pTplteOnlyOneView->GetFirstDocPosition();
if( NULL == Pos ) { m_pTplteOnlyOneView->OpenDocumentFile(NULL); return;
}
CDocument *pDoc = m_pTplteOnlyOneView->GetNextDoc(Pos);
if( NULL == pDoc ) { m_pTplteOnlyOneView->OpenDocumentFile(NULL); return;
}
Pos = pDoc->GetFirstViewPosition();
if( NULL == Pos ) { m_pTplteOnlyOneView->OpenDocumentFile(NULL); return;
}
CView *pView = pDoc->GetNextView(Pos);
if( NULL == pView ) { m_pTplteOnlyOneView->OpenDocumentFile(NULL); return;
}
CWnd *pWnd = pView->GetParent();
if( NULL == pWnd ) { m_pTplteOnlyOneView->OpenDocumentFile(NULL); return;
}
WINDOWPLACEMENT wpl;
pWnd->GetWindowPlacement(&wpl);
if( SW_SHOWMINIMIZED == wpl.showCmd ) { wpl.showCmd = SW_RESTORE;
if( WPF_RESTORETOMAXIMIZED == wpl.flags )
wpl.showCmd = SW_SHOWMAXIMIZED;
pWnd->SetWindowPlacement(&wpl);
}
else
{ wpl.showCmd = SW_RESTORE; pWnd->SetWindowPlacement(&wpl);
pWnd->BringWindowToTop();
}
}
That does the trick.If you want to open this document with a file, provide the filename to the
OpenDocumentFile function. Of course then you also have to take care of the contents of the old view, before filling in a new one.
If you have more document types, where only one view should be allowed, just add another CMultiDocTemplate* variable, another command handler, paste the code and adjust the names.