Click here to Skip to main content
11,637,415 members (64,841 online)
Click here to Skip to main content

CMDITabs

, 19 Oct 2001 CPOL 315.8K 11.2K 122
Rate this:
Please Sign up or sign in to vote.
A CTabCtrl control to switch comfortably between MDI views

Overview

A feature I always missed in most MDI products (like Microsoft Word or Microsoft FrontPage) was a simple means to see which views/docs are currently open and to switch easily between them. Using the 'Window' menu can be quite cumbersome. I wanted something like Oz Solomonovich's Window Tabs Add-In. In my current project I have to do an MDI application with several different views and I don't want my users to become as frustrated as me about this topic. So I decided to make my own CTabCtrl derivation. As it turns out, it was very easy to do so.

CMDITabs is a little control that adds 'tabs' to an MFC MDI application with which the user can switch between views. The appearance can also be customized to display the view icons. This is useful if you have different types of views, otherwise I would suggest to turn the icons off. The tabs can be placed at the bottom or at the top of the views. The control is smart enough to reflect all changes in the views (open, close, new, change title/icon).

After writing this article I discovered, that there is a similar solution for tabbing between MDI views in the doc/view section of Code Project. First I was a little bit frustrated, thinking I had reinvented the wheel again Wink | ;-) . But on a closer look I liked my MDITabs better because of three reasons:

  1. it looks nicer and hasn't got a space wasting double border frame
  2. it is more stable due to its simpler implementation Wink | ;-) (read the bug list in the comments)
  3. it is smaller, you have only one class to use, not three

So I sent this article int to the Code Project.

How to use

Using CMDITabs in your code is extremely simple. Add MDITabs.h and MDITabs.cpp to your project. In your CMainFrame class add a new member m_wndMDITabs of class CMDITabs (don't forget to include 'MDITabs.h'). Insert m_mdiTabs.Create(this); in CMainFrame::OnCreate() after all toolbars and status bars have been set up created. It is important for proper layout that the MDI tabctrl is created last. To synchronize view operations with the MDI Tabs, it is necessary to override OnUpdateFrameTitle from the base class CMDIFrameWnd of our CMainFrame class. After calling the base class implementation you have to call the Update() function of m_wndMDITabs

// MainFrm.h
class CMainFrame : public CMDIFrameWnd
{
  [...]
  CMDITabs m_wndMDITabs;
  
  virtual void OnUpdateFrameTitle(BOOL bAddToTitle); 
  [...]  
};

// MainFrm.cpp
void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
  CMDIFrameWnd::OnUpdateFrameTitle(bAddToTitle);
  m_wndMDITabs.Update(); // sync the mditabctrl with all views
}

That's it! Build and start your application, open some views and enjoy switching between them Wink | ;-)

Other features

  • Double clicking on a tab maximizes the view.
  • Right clicking on a tab displays the view's system menu. You can change the menu by simply changing the views system menu, if you like (see demo project CChildFrame::OnCreate()). If you need to supply a total different (independant) menu, your view can answer the WM_GETTABSYSMENU message.
  • The tabs are hidden when there are less than one (two) view(s) open. Use SetMinViews() or the style MT_HIDEWLT2VIEWS to change this behaviour.
  • In the Create() function you can supply some styles to customize the appearance of the control:
    MT_BOTTOM tabs appear at bottom
    MT_TOP tabs appear at top
    MT_IMAGES use view icons as images
    MT_HIDEWLT2VIEWS hide tabs when there are less than two views (default is one view)
  m_wndMDITabs.Create(this, MT_TOP|MT_IMAGES|MT_HIDEWLT2VIEWS);

Internals

Layout

The private MFC message WM_SIZEPARENT provides a way to attach windows to the MDI client area of a doc/view app. CMDITabs implements OnSizeParent to attach itself at the bottom of the MDI client area. If you want another layout you need to change this function. The Z-order of the MDIClient siblings is important for the layout algorithm. Siblings are asked to position themselves in Z-order (search for WM_SIZEPARENT on MSDN to get more info). That's the reason why CMDITabs must be created after all other control and status bars have been done in CMainFrame::OnCreate(). Otherwise the status bar would appear above the tabs, destroying proper layout.

Synchronizing Views and Tabs

The tab control must always reflect the list of views. Instead of monitoring all possible view changing events (close, open, new, changing titles/icons) I hooked into the CMainFrame::OnUpdateFrameTitle() function. I discovered, that this function gets called when something view-related happens. Here you have to call CMDITabs::Update() which in response completely rebuilds its tab list. It does so by querying the child windows of the MDIClient window, circumventing the complex doc/view organization of MFC! The simpler the solution the robuster it works!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Christian Rodemeyer
Architect AutoScout24 GmbH
Germany Germany
I'm developing for fun since 1985, starting with UCSD Pascal on some old machines (no hard disk, but four floppies!), then moving quickly on to assembler on the famous C64 and Amiga. During university I started professional development for Windows/Unix/Linux, using a myriad of languages (Pi, Assembler (6502, 68000, 80386/486), Cobol, Modula2, OML, C, C++, C#, Java, Scala, Clojure VB, Prolog, Eiffel, Delphi, Perl, Pascal). Currently my favorite languages are Clojure and Ruby.

You may also be interested in...

Comments and Discussions

 
Generalnice work Pin
Biruk Abebe13-Apr-15 8:27
memberBiruk Abebe13-Apr-15 8:27 
GeneralMy vote of 5 Pin
chaos_xia10-Jul-12 4:07
memberchaos_xia10-Jul-12 4:07 
GeneralDrag to change order of tabs - *solution* (wohoo) Pin
Gernot Frisch3-Nov-09 5:02
memberGernot Frisch3-Nov-09 5:02 
GeneralRe: Drag to change order of tabs - *solution* (wohoo) Pin
Jason Tian23-Jul-11 22:12
memberJason Tian23-Jul-11 22:12 
QuestionHow to use in SDI application ? Pin
Gobsek7-Jul-09 23:47
memberGobsek7-Jul-09 23:47 
Generalsimply to use indeed Pin
dickens200821-Nov-08 19:50
memberdickens200821-Nov-08 19:50 
GeneralExtending up and down Pin
Vaclav_Sal26-Sep-07 4:57
memberVaclav_Sal26-Sep-07 4:57 
QuestionWM_SIZEPARENT Pin
Mark_VC28-Aug-07 3:10
memberMark_VC28-Aug-07 3:10 
QuestionWork in Visual Studio like interface Pin
9353201823-May-07 16:00
member9353201823-May-07 16:00 
Generalcontrol the child window Pin
coronys4-Jan-07 7:50
membercoronys4-Jan-07 7:50 
GeneralNICE Pin
ajs218-May-06 15:34
memberajs218-May-06 15:34 
GeneralVS. NET 2005 - MFC 8.0 LNK 2019 Pin
BrownJacket26-Dec-05 8:24
memberBrownJacket26-Dec-05 8:24 
GeneralRe: VS. NET 2005 - MFC 8.0 LNK 2019 Pin
zhangyuan_cau3-Feb-06 17:02
memberzhangyuan_cau3-Feb-06 17:02 
QuestionHow to create more than one object of forma? Pin
zhangwm18-Sep-05 23:48
memberzhangwm18-Sep-05 23:48 
GeneralFlorin Octavian Ochiana's Code Pin
Dr.Funk14-Sep-05 19:03
memberDr.Funk14-Sep-05 19:03 
GeneralTab text Color Pin
Fad B16-Jul-05 20:42
memberFad B16-Jul-05 20:42 
QuestionHow to hide this control directly, i.e. form main menu, for example (sorry for bad English)? Pin
Bazzam13-May-05 6:23
memberBazzam13-May-05 6:23 
GeneralXP Style Pin
ehh22-Mar-05 8:35
memberehh22-Mar-05 8:35 
GeneralRe: XP Style Pin
Jonathan Attias15-Aug-05 7:26
memberJonathan Attias15-Aug-05 7:26 
QuestionIcon ??? Pin
DJ Mantra16-Jan-05 0:56
memberDJ Mantra16-Jan-05 0:56 
GeneralPlease correct text Pin
Alexander Shevchenko31-Oct-04 9:46
memberAlexander Shevchenko31-Oct-04 9:46 
GeneralOnSizeParent - problem + solution Pin
adrian_conlon25-Feb-04 2:02
memberadrian_conlon25-Feb-04 2:02 
GeneralRe: OnSizeParent - problem + solution Pin
Hockey27-Apr-04 16:29
memberHockey27-Apr-04 16:29 
GeneralRe: OnSizeParent - problem + solution Pin
adrian_conlon28-Apr-04 5:50
memberadrian_conlon28-Apr-04 5:50 
GeneralMDI Tabs Code Licence Pin
narm8-Nov-03 17:58
sussnarm8-Nov-03 17:58 
GeneralRe: MDI Tabs Code Licence Pin
Christian Rodemeyer9-Nov-03 7:14
memberChristian Rodemeyer9-Nov-03 7:14 
GeneralRemove tab title order number Pin
zhj9-Oct-03 6:43
memberzhj9-Oct-03 6:43 
Questionhow to specify form type not select from box when create new tab? Pin
yangguoqiang17-Sep-03 18:40
memberyangguoqiang17-Sep-03 18:40 
GeneralXP Drawing problem Pin
Obliterator16-Sep-03 3:33
memberObliterator16-Sep-03 3:33 
GeneralDocument and its views tabs needed Pin
Vaclav16-Aug-03 15:54
memberVaclav16-Aug-03 15:54 
GeneralFlick Question Pin
storein9-Jun-03 0:17
memberstorein9-Jun-03 0:17 
GeneralRe: Flick Question Pin
selecta13-Jun-03 14:53
memberselecta13-Jun-03 14:53 
GeneralRe: Flick Question Pin
storein16-Jun-03 14:56
memberstorein16-Jun-03 14:56 
GeneralProblem when using TCS_BUTTON style... Pin
selecta28-May-03 11:25
memberselecta28-May-03 11:25 
GeneralRe: Problem when using TCS_BUTTON style... Pin
selecta28-May-03 11:51
memberselecta28-May-03 11:51 
Generalwhen select change tab how to transfer the function of view Pin
maohj168816-Mar-03 18:21
membermaohj168816-Mar-03 18:21 
GeneralWindow Text as tab text Pin
ajl8793-Feb-03 10:40
memberajl8793-Feb-03 10:40 
GeneralSaving and Loading Muliple Views Pin
ajl87917-Jan-03 3:31
memberajl87917-Jan-03 3:31 
GeneralOnUpdateFrameTitle() Pin
Kannan Ramanathan17-Nov-02 20:26
memberKannan Ramanathan17-Nov-02 20:26 
GeneralIs there any way not to let to close the MDItab by pressing Ctrl+F4 Pin
PL22-Oct-02 18:38
sussPL22-Oct-02 18:38 
GeneralFlicking problem Pin
Anonymous16-Oct-02 21:58
sussAnonymous16-Oct-02 21:58 
GeneralRe: Flicking problem Pin
kimdaejeong28-Apr-03 8:14
susskimdaejeong28-Apr-03 8:14 
GeneralRe: Flicking problem Pin
gu mingqiu9-Mar-04 17:34
membergu mingqiu9-Mar-04 17:34 
GeneralTitle sync problem Pin
Obliterator14-Aug-02 9:44
memberObliterator14-Aug-02 9:44 
GeneralRe: Title sync problem Pin
Anonymous15-Aug-02 10:12
sussAnonymous15-Aug-02 10:12 
GeneralRe: Title sync problem Pin
Obliterator16-Aug-02 0:38
memberObliterator16-Aug-02 0:38 
GeneralRe: Title sync problem *FIX* Pin
Albert van Peppen11-Dec-02 2:32
memberAlbert van Peppen11-Dec-02 2:32 
GeneralRe: Title sync problem *FIX* Pin
Obliterator11-Dec-02 4:15
memberObliterator11-Dec-02 4:15 
GeneralRe: Title sync problem *FIX* Pin
Albert van Peppen11-Dec-02 4:26
memberAlbert van Peppen11-Dec-02 4:26 
GeneralRe: Title sync problem *FIX* Pin
Obliterator11-Dec-02 5:13
memberObliterator11-Dec-02 5:13 

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
Web04 | 2.8.150728.1 | Last Updated 20 Oct 2001
Article Copyright 2001 by Christian Rodemeyer
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid