![]() |
Desktop Development »
Document / View »
General
Intermediate
License: The Code Project Open License (CPOL)
A Tabbed MDI Frame WindowBy Ernesto Perales SotoA tabbed frame window to show several views of a document in a single frame. |
VC7WinXP, MFC, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
In a recent project, I wanted to show the document data using different views. I didn't like the default MFC implementation, creating a new frame window for each view.
I headed to Code Project and found several tabbed window articles (Property Sheet View, A Multi Document Tabbed Interface, etc.) but none was exactly what I needed: one frame per document, and one tab per view. With a little help from Google, I found an old article at CodeGuru named "Tabbed Views" by Salvatore Mosaico. I took the original idea, removed the grouping feature, and created this class, adding support for another feature I needed: tool bars and status bars in the child frame.
CTabbedMDIChildWnd. If you do this by hand, remember to define the message map and dynamic creation. You can use the class wizard to do the dirty work for you.

CMDIChildWnd as the base class:

CMDIChildWnd with our class. Do this both in the *.h and *.cpp files:

CTabbedMDIChildWnd header in the *.h. #include "TabbedMDIChildWnd.h"
#include "FirstView.h"
#include "SecondView.h"
CTabbedMDIChildWnd::CTabItem. This class is derived form TCITEM, with the addition of a CRuntimeClass to create the view. You can use the provided constructor as in the next example. OnCreateClient. Inside the function, define the tabs, and call the base class: BOOL CDemoChildWnd::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* pContext)
{
// this is the heart of the class, each call to DefineView will
// add a tab of the specified class
DefineTab(CTabbedMDIChildWnd::CTabItem(_T("First View"),
RUNTIME_CLASS(CFirstView)));
DefineTab(CTabbedMDIChildWnd::CTabItem(_T("Second View"),
RUNTIME_CLASS(CSecondView)));
return CTabbedMDIChildWnd::OnCreateClient(lpcs,pContext);
}
InitInstance function of the application: // Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_TabbedFrameTYPE,
RUNTIME_CLASS(CTabbedFrameDoc),
RUNTIME_CLASS(CDemoChildWnd), // custom MDI child frame
RUNTIME_CLASS(CTabbedFrameView));
AddDocTemplate(pDocTemplate);
The class has a CTabCtrl member and creates one tab for each view defined by a call to DefineTab. It handles the TCN_SELCHANGE and TCN_SELCHANGING notify messages to hide and show the views as the tabs are selected.
It uses a std::vector to keep track of the defined tabs using the runtime class of the different views. This implementation imposes a limitation, only one instance of a view class is supported. Calling DefineTab several times using the same runtime class is not a good idea!
If you want to change the appearance of the tab control, you can customize CTabbedMDIChildWnd::OnCreateClient to change the styles of the tab control, or make additional calls to add images, etc.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 12 Mar 2008 Editor: Deeksha Shenoy |
Copyright 2004 by Ernesto Perales Soto Everything else Copyright © CodeProject, 1999-2009 Web09 | Advertise on the Code Project |