Click here to Skip to main content
15,881,204 members
Articles / Desktop Programming / MFC
Article

Sizing TabControlBar

Rate me:
Please Sign up or sign in to vote.
3.65/5 (23 votes)
7 Feb 2000 346K   4.6K   92   77
Creates a dockable and resizable control bar.
  • Download demo project - 46 Kb
  • Sample Image - Sizing_Tabctl.jpg

    This article extends the article CSizingControlBar - a resizable control bar by Cristi Posea.
    Webmaster's note: the CSizingControlBar class used in this code is an earlier version; follow the link above for the latest one.

    Features

    The Control bar like in DevStudio, which has TabControls with different Views (like TreeViews) and it can be docked and resized.

    Instructions

    Add the following class to your project:

    • CSizingControlBar
    • CSizingTabCtrlBar

    Add a member variable to CMainFrame (in mainfrm.h):

    CSizingTabCtrlBar m_wndSTCBar;

    Create the bar in CMainFrame::OnCreate(). Then set bar styles, enable it to dock... like any control bar. Be sure to add IDW_PROP_BAR to the "resource.h" and to add the bitmap IDB_TABIMAGES Image 2 to your resources.

    // SizingControlBar
    m_wndSTCBar.Create(this, CSize(200, 1), IDW_PROP_BAR);
    m_wndSTCBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
    	CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndSTCBar.EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndSTCBar, AFX_IDW_DOCKBAR_LEFT);
    
    m_wndSTCBar.AddView("Database", RUNTIME_CLASS(CClassView));
    m_wndSTCBar.AddView("Files", RUNTIME_CLASS(CFileView));

    As you can see, the different views are added by calling

    m_wndSTCBar.AddView("Files", RUNTIME_CLASS(CFileView));

    Thats the only thing you have to do, to add a view!

    Override CMainFrame::RecalcLayout().
    Note: use the base framewnd class member function, ie if you have an SDI application replace CMDIFrameWnd with CFrameWnd below.

    void CMainFrame::RecalcLayout(BOOL bNotify) 
    {
    	CMDIFrameWnd::RecalcLayout(bNotify);
    	CMDIFrameWnd::RecalcLayout(bNotify);
    }

    To call a view from the Mainframe:

    CFileView* pView = (CFileView*)
    	m_wndSTCBar.GetView(RUNTIME_CLASS(CFileView));
    pView->UpdateView();	// or do anything else
    m_wndSTCBar.SetActiveView(RUNTIME_CLASS(CFileView));

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Germany Germany
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    Questionthis had bugs Pin
    xiaoniao12349-Nov-23 1:02
    xiaoniao12349-Nov-23 1:02 
    QuestionMainframe events gets disabled Pin
    D L Deepthi26-Apr-07 0:01
    D L Deepthi26-Apr-07 0:01 
    GeneralCode not maintained anymore Pin
    Dirk Clemens25-Jan-05 5:41
    Dirk Clemens25-Jan-05 5:41 
    GeneralDamm! Not Working Pin
    Member 10916253-Jan-05 16:34
    Member 10916253-Jan-05 16:34 
    GeneralThe shorter way, please help fix Pin
    New Student27-Nov-04 11:28
    New Student27-Nov-04 11:28 
    I like this dock window but it seems to give me some trouble. I need two tabs with different treeview. I've learned a lot from here but need some corrections. Thanks to Mark Conway from CodeGuru (Dock demo/docktest).But I did not use those dlls, I have combine from there and here, based on CSizingControlBar. I did not create any special class to support the treeview like the sample "MY Bar", but I lost something, here:

    This is cpp: I define the ID tab here.
    #define IDC_TREEBAR_TAB 1001

    ///////////////////////////////////////////////////////////////////////////// I use workspace instead My Bar.
    // CWorkspaceBar

    CWorkspaceBar::CWorkspaceBar()
    {

    }

    CWorkspaceBar::~CWorkspaceBar()
    {

    }


    BEGIN_MESSAGE_MAP(CWorkspaceBar, CSuperControlBarG)
    //{{AFX_MSG_MAP(CWorkspaceBar)
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_DESTROY()
    ON_NOTIFY(TCN_SELCHANGE, IDC_TREEBAR_TAB, OnTabChange)
    //}}AFX_MSG_MAP

    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CWorkspaceBar message handlers

    int CWorkspaceBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CSuperControlBarG::OnCreate(lpCreateStruct) == -1)
    return -1;

    // Create tab control
    CRect rect(0, 0, 0, 0);
    rect.SetRectEmpty();
    // Create Tab window

    if (!m_TabCtrl.Create(WS_VISIBLE | WS_CHILD | TCS_BOTTOM | TCS_MULTILINE,
    rect, this,IDC_TREEBAR_TAB))
    {
    TRACE0("Failed to create workspace tab window\n");
    return -1;
    }
    m_TabCtrl.SetFont(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
    m_Images.Create(IDB_TABIMAGES, 16, 1, RGB (255, 0, 255));
    m_TabCtrl.SetImageList(&m_Images);

    // create tree window here

    //Populate tab
    LPCTSTR szTabName[] = { _T("400 Series"), _T("Xpres") };

    for (int i = 0; i < sizeof(szTabName) / sizeof(LPCTSTR); i++)
    {
    CTreeCtrl * pTreeCtrl = new CTreeCtrl;

    DWORD dwStyle = WS_BORDER | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS |
    TVS_LINESATROOT | TVS_SHOWSELALWAYS;

    if (!pTreeCtrl->Create(dwStyle, rect, this, i))
    {
    TRACE0 ("Failed to create tree control\n");
    return -1;
    }

    pTreeCtrl->ModifyStyleEx(0, WS_EX_CLIENTEDGE);

    TC_ITEM TCI;
    TCI.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE;
    TCI.pszText = (char *)szTabName[i];
    TCI.lParam = (LPARAM)pTreeCtrl;
    TCI.iImage = i;
    VERIFY(m_TabCtrl.InsertItem(0, &TCI) != -1);


    switch (i)
    {
    case 0:
    {
    HTREEITEM hHiWay =
    pTreeCtrl->InsertItem (" 400 Series",TVI_ROOT);
    pTreeCtrl->InsertItem (" 400",hHiWay);
    pTreeCtrl->InsertItem (" 401",hHiWay);

    HTREEITEM hXpresWays =
    pTreeCtrl->InsertItem (" EXpress",TVI_ROOT);
    pTreeCtrl->InsertItem (" QEW",hXpresWay);
    pTreeCtrl->InsertItem (" HWY 7",hXpresWay);
    }
    break;

    case 1:
    {
    HTREEITEM hXpresWays =
    pTreeCtrl->InsertItem (" EXpress",TVI_ROOT);
    pTreeCtrl->InsertItem (" QEW",hXpresWay);
    pTreeCtrl->InsertItem (" HWY 7",hXpresWay);

    HTREEITEM hHiWay =
    pTreeCtrl->InsertItem (" 400 Series",TVI_ROOT);
    pTreeCtrl->InsertItem (" 400",hHiWay);
    pTreeCtrl->InsertItem (" 401",hHiWay);
    }
    break;

    }

    }


    ShowSelTabWindow();

    return 0;

    }

    CWnd * CWorkspaceBar::GetTabWindow(int nTab)
    {
    TC_ITEM TCI;
    TCI.mask = TCIF_PARAM;
    m_TabCtrl.GetItem(nTab, &TCI);
    CWnd * pWnd = (CWnd *)TCI.lParam;
    ASSERT(pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CWnd)));
    return pWnd;
    }

    void CWorkspaceBar::OnTabChange( NMHDR * pNM, LRESULT * pResult )
    // hide all the windows - except the one with the currently selected tab
    {
    ShowSelTabWindow();
    *pResult = TRUE;

    }


    void CWorkspaceBar::ShowSelTabWindow()
    {
    m_TabCtrl.GetCurSel();
    int nSel = m_TabCtrl.GetCurSel();
    ASSERT(nSel != -1);

    for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
    {
    GetTabWindow(i)->ShowWindow(i == nSel ? SW_SHOW : SW_HIDE);
    }
    }


    void CWorkspaceBar::OnSize(UINT nType, int cx, int cy)
    {
    CSizingControlBarG::OnSize(nType, cx, cy);

    // m_TabCtrl.SetWindowPos (NULL, -1, -1, cx, cy,
    // SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);

    CRect rect(0, 0, cx, cy);
    if (IsFloating())
    rect.InflateRect(-2, -2); // give space around controls.
    else
    rect.InflateRect(-4, -4);
    // reposition the tab control.
    m_TabCtrl.MoveWindow(&rect);
    m_TabCtrl.AdjustRect(FALSE, &rect);

    for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
    {
    GetTabWindow(i)->MoveWindow(&rect);
    }
    Invalidate();
    }

    void CWorkspaceBar::OnDestroy()
    {
    CSizingControlBarG::OnDestroy();

    for (int i = 0; i < m_TabCtrl.GetItemCount(); i++)
    {
    delete GetTabWindow(i);
    }

    }

    This header file:

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // WorkspaceBar.h : header file
    //
    #include <afxtempl.h>

    #include "SizingControlBarG.h"
    /////////////////////////////////////////////////////////////////////////////
    // CWorkspaceBar window


    class CWorkspaceBar : public CSizingControlBarG
    {
    // Construction
    public:
    CWorkspaceBar();

    // Attributes
    public:
    CTabCtrl m_TabCtrl;
    CImageList m_Images;

    // Operations
    public:

    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CWorkspaceBar)
    //}}AFX_VIRTUAL

    // Implementation
    public:
    virtual ~CWorkspaceBar();

    // Generated message map functions
    protected:
    // int m_nActiveTab;
    //{{AFX_MSG(CWorkspaceBar)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnSize(UINT nType, int cx, int cy);

    afx_msg void OnDestroy();
    //}}AFX_MSG
    CWnd * GetTabWindow(int nTab);
    void ShowSelTabWindow();
    afx_msg void OnTabChange( NMHDR * pNotifyStruct, LRESULT * result );

    DECLARE_MESSAGE_MAP()
    };


    It looks quite simple but needs fix.
    GeneralWinFrm2.cpp and bardock errors Pin
    Furries24-Nov-04 5:46
    Furries24-Nov-04 5:46 
    GeneralNot work with either vs6 Pin
    New Student21-Nov-04 11:52
    New Student21-Nov-04 11:52 
    GeneralCommand message handling in views inside this bar Pin
    atali21-Oct-04 6:18
    atali21-Oct-04 6:18 
    GeneralRedraw the bar after adding a view Pin
    atali21-Oct-04 6:11
    atali21-Oct-04 6:11 
    GeneralSupport for top and multiline taps Pin
    Jaime Olivares8-Jul-04 14:33
    Jaime Olivares8-Jul-04 14:33 
    GeneralBetter version Pin
    Jaime Olivares8-Jul-04 14:52
    Jaime Olivares8-Jul-04 14:52 
    QuestionBugs? Pin
    Algorismus24-Apr-04 3:51
    Algorismus24-Apr-04 3:51 
    GeneralProblem with CSizingTabCtrlBar by Dirk Clemens Pin
    redsome25-Mar-04 14:43
    redsome25-Mar-04 14:43 
    GeneralProg crash by klick on X Pin
    LowFly18-Mar-04 5:04
    LowFly18-Mar-04 5:04 
    GeneralMutch Better Layout Code Pin
    MOX10-Mar-04 7:28
    MOX10-Mar-04 7:28 
    GeneralRe: Mutch Better Layout Code Pin
    Kybert9-Apr-04 11:47
    Kybert9-Apr-04 11:47 
    GeneralRe: Mutch Better Layout Code Pin
    Anonymous19-Apr-04 9:59
    Anonymous19-Apr-04 9:59 
    AnswerRe: Mutch Better Layout Code Pin
    Thornets30-Jul-08 22:52
    Thornets30-Jul-08 22:52 
    Generalissue when closing with floating bar Pin
    avcode4-Mar-04 21:43
    avcode4-Mar-04 21:43 
    GeneralDocking - TOP , BOTTOM Pin
    Member 66505420-Feb-04 20:39
    Member 66505420-Feb-04 20:39 
    GeneralProblems with Mouse Click Pin
    salman29-Dec-03 20:04
    salman29-Dec-03 20:04 
    Generalwheel mouse capture problem Pin
    stevehaigh8-Nov-03 11:21
    stevehaigh8-Nov-03 11:21 
    GeneralClosing CSizingControlBar Pin
    DMD31-Jul-03 10:48
    DMD31-Jul-03 10:48 
    GeneralRe: Closing CSizingControlBar Pin
    xiaobin9-Aug-03 22:55
    xiaobin9-Aug-03 22:55 
    GeneralNot work well in VS.net 2003!! Pin
    Yoyoboy31-Jul-03 2:56
    Yoyoboy31-Jul-03 2:56 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.