viksoe.dk

Tabbed Dialog Container control

Tabbed Dialog Container control


This article was submitted .


Usually when you use a Tab control, you want to embed a number of views in it. Preferably, it would be nice if one could just insert a number of dialog classes into the CTabCtrl class and use them as views.
Unfortunately, the standard Tab control does not have this functionality. It's relatively easy to add, so Microsoft built a PropertySheet wrapper for this reason. But even with this widget, you often miss complete control of what is going on. It also tends to do a lot of stuff to support a wizard-type look.

The Tabbed Dialog Container, on the other hand, is a bare bone Tab control. It actually contains two controls.

  • One is a Tab control with the "easy to add window views" feature. The control eases the management of adding and maintaining dialogs and other windows (views) into the regular Windows™ Tab control.
  • The base control, however, is a simple child window, which manages the views, and does not display tabs or any other GUI, except for placing the active view in its client area. The base control, called CDlgContainerCtrl, allows any number of views to be added and sends notification when a view becomes visible or selected.
There are plenty of cools things you can use the CDlgContainerCtrl control for, among others a custom Options dialog as demonstrated in my XP UI Sample.

How to use it

To add the Tab container, place a Tab control on a dialog. Add a member variable...
CDialogTabCtrl m_ctrlTab
In the OnInitDialog() event handler, add the following line:
  LRESULT OnInitDialog(UINT /*uMsg*/, 
                       WPARAM /*wParam*/, 
                       LPARAM /*lParam*/, 
                       BOOL& /*bHandled*/)
  {
    ...
    m_ctrlTab.SubclassWindow(GetDlgItem(IDC_TAB1));
    ...
  }
Create views and add them. Same functionality as the regular CTabCtrl control.
  m_view1.Create(m_hWnd);

  TCITEM tci = { 0 };
  tci.mask = TCIF_TEXT;
  tci.pszText = _T("View 1");
  m_ctrlTab.InsertItem(0, &tci, m_view1);
After adding the views, call SetCurSel() to select a view.
  m_ctrlTab.SetCurSel(0)
Remember to add a reflection macro to the parent window's message map:
  BEGIN_MSG_MAP(CMainDlg)
    ...
    REFLECT_NOTIFICATIONS()
  END_MSG_MAP()

When a view is added to the control, the view's parent is changed to a container window internal to the tab. Do not send messages to this parent.

Use the following line...

   m_ctrlTab.Uxtheme_EnableThemeDialogTexture(m_view1, ETDT_ENABLETAB);
...to enable Windows XP painting of your dialog that matches the tab default interior.

Source Code Dependencies

Microsoft Visual C++ 6.0
Microsoft WTL 7.0 Library

Download Files

DownloadSource Code (4 Kb)
Sample Project (44 Kb)

To the top