We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

tab control for multiple views

kbb
kbb asked
on
Medium Priority
724 Views
Last Modified: 2013-11-19
I have an SDI application that has multiple views. I create all of the views when the document is opened, and then show only the one that is selected, hiding the others.

What I would like is to use a CTabCtrl to switch between the views. But I don't know how to (or where to) attach the control.

Any help would be greatly appreciated
Comment
Watch Question

Commented:
I have at least four sets of saomple code showing how to do this - each uses a slightly different method (eg. its own tab class, using CTabCtrl, using PropertySheets etc).

I can send these to you if you give me your eMail address - mine is Roger_Onslow@compsys.com.au

NOTE: There are lots of ways of acheiving this - it is best if your look at several example and work out the best solution for your particular application.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Commented:
PS: Here is one of the smaller sets of sample code... I'll eMail it to you with the others I have when you send me your eMail address.

// TabView.h : interface of the CTabView class
//
/////////////////////////////////////////////////////////////////////////////

#ifndef _TABVIEW_H
#define _TABVIEW_H
class CTabView : public CCtrlView
{
      DECLARE_DYNCREATE(CTabView)
protected: // create from serialization only
      CTabView();

// Attributes
public:
      CTabCtrl& GetTabCtrl() const;
      CDocument* GetDocument();      // Change this to more generic doc
      CObArray m_VwList;                        // List of pointers to tab child views
      CImageList m_ctlImage;                  // Keep Image List on the stack?
      int m_nTabCount;                        // How many Tabs are there?
      int m_nActiveTab;                        // Zero based number of selected tab
      int m_nLastActiveTab;                  // Zero based number of last selected tab
      BOOL m_bCreated;                        // Flag - True after 'OnInitialUpdate'
      BOOL m_bSizing;                              // Flag - True after 'OnSize'
      CFont* m_pFont;                              // Smaller Default font
      CRect m_rOldRect;
      int m_nMarginPixels;                        // how big is the margin?

// Overridables
protected:
      virtual void RemoveImageList(int nImageList);
      virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
      virtual BOOL AddTab(int nTab, int nImage, LPSTR csCaption);
   virtual BOOL AddTab(int nTab, int nImage, UINT nCaptionID);
   virtual BOOL RemoveTab(int nTab);
      virtual BOOL RemoveAllTabs();
      virtual int GetSelectedTab();
      virtual int GetTabCount();
      virtual void SetTabCount(int nCount);
      virtual void SetImageList(int nImageListID);
      virtual BOOL GetChildRect(CRect& rVwRect);
      // Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CTabView)
      public:
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
      virtual BOOL DestroyWindow();
      virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult);
      virtual void OnInitialUpdate();
      protected:
      virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
      virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnDraw(CDC* pDC);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CTabView();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
      //{{AFX_MSG(CTabView)
      afx_msg BOOL OnEraseBkgnd(CDC* pDC);
      afx_msg void OnSize(UINT nType, int cx, int cy);
      afx_msg void OnSysColorChange();
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in TabView.cpp
inline CDocument* CTabView::GetDocument()
   { return (CDocument*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////
#endif
=========================

// TabView.cpp : implementation of the CTabView class
//

#include "stdafx.h"
#include "ownsetup.h"

#include "TabView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTabView

IMPLEMENT_DYNCREATE(CTabView, CCtrlView)

BEGIN_MESSAGE_MAP(CTabView, CCtrlView)
      //{{AFX_MSG_MAP(CTabView)
      ON_WM_ERASEBKGND()
      ON_WM_SIZE()
      ON_WM_SYSCOLORCHANGE()
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTabView construction/destruction

CTabView::CTabView() : CCtrlView(WC_TABCONTROL,AFX_WS_DEFAULT_VIEW | TCS_FOCUSNEVER)
{
      m_nTabCount = 0;
      m_nActiveTab = -1;
      m_nLastActiveTab = -1;
      m_bCreated = FALSE;
      m_bSizing = FALSE;
      m_nMarginPixels = 0;
   m_pFont = NULL;
}

CTabView::~CTabView()
{

   if (m_pFont)
      delete m_pFont;
}

BOOL CTabView::PreCreateWindow(CREATESTRUCT& cs)
{
      return CCtrlView::PreCreateWindow(cs);
}


/////////////////////////////////////////////////////////////////////////////
// CTabView printing

BOOL CTabView::OnPreparePrinting(CPrintInfo* pInfo)
{
      // default preparation
      return DoPreparePrinting(pInfo);
}

void CTabView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
      // TODO: add extra initialization before printing
}

void CTabView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
      // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CTabView diagnostics

#ifdef _DEBUG
void CTabView::AssertValid() const
{
      CCtrlView::AssertValid();
}

void CTabView::Dump(CDumpContext& dc) const
{
      CCtrlView::Dump(dc);
}

CDocument* CTabView::GetDocument() // non-debug version is inline
{
      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDocument)));
      return (CDocument*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTabView message handlers
CTabCtrl& CTabView::GetTabCtrl() const
{
      return *(CTabCtrl*)this;
}

BOOL CTabView::GetChildRect(CRect& rVwRect)
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      CRect rTabRect;
      CRect rParentRect;
      CPoint pntTabBottom;
      
      GetClientRect(rParentRect);
      BOOL bGotItemRect = ctlTab.GetItemRect(0,rTabRect);
      pntTabBottom = rTabRect.BottomRight();
      pntTabBottom.x = 0;
      CPoint pntPrntBottomRight = rParentRect.BottomRight();
      CRect rTempViewRect(pntTabBottom,pntPrntBottomRight);
      rTempViewRect.DeflateRect(m_nMarginPixels, m_nMarginPixels);
      rVwRect = rTempViewRect;
      return TRUE;
}

BOOL CTabView::AddTab(int nTab, int nImage, UINT nCaptionID)
{
   CString Caption;
   Caption.LoadString(nCaptionID);
   return AddTab(nTab, nImage, Caption.GetBuffer(1));
}

BOOL CTabView::AddTab(int nTab, int nImage, LPSTR csCaption)
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      TC_ITEM thisItem;

      if (csCaption != NULL)
            thisItem.mask = TCIF_TEXT|TCIF_IMAGE;
      else
            thisItem.mask = TCIF_IMAGE;

      thisItem.pszText = csCaption;
      thisItem.iImage = nImage;

      return ctlTab.InsertItem(nTab,&thisItem);
}

BOOL CTabView::RemoveTab(int nTab)
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      return ctlTab.DeleteItem(nTab);
}

BOOL CTabView::RemoveAllTabs()
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      return ctlTab.DeleteAllItems( );
}

int CTabView::GetSelectedTab()
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      return ctlTab.GetCurSel();
}

int CTabView::GetTabCount()
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      return ctlTab.GetItemCount();
}

void CTabView::SetTabCount(int nCount)
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      m_nTabCount = GetTabCount();
}

void CTabView::SetImageList(int nImageListID)
{
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
      m_ctlImage.Create(nImageListID,16,0,RGB(255,255,255));
      m_ctlImage.SetBkColor(GetSysColor(COLOR_3DFACE));

      ctlTab.SetImageList(&m_ctlImage);
}


void CTabView::RemoveImageList(int nImageList)
{
      HIMAGELIST h = (HIMAGELIST)SendMessage(TCM_GETIMAGELIST,(WPARAM)nImageList);
      if(CImageList::FromHandlePermanent(h) != NULL)
      {
            SendMessage(TCM_SETIMAGELIST, (WPARAM)nImageList, NULL);
      }
}


BOOL CTabView::DestroyWindow()
{
      RemoveImageList(0);                        //Only One Image list is possible

      return CCtrlView::DestroyWindow();
}

void CTabView::DrawItem(LPDRAWITEMSTRUCT)
{
      ASSERT (FALSE);
}

BOOL CTabView::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
      LRESULT* pResult)
{
      
      if( message == WM_NOTIFY)
      {
            NMHDR* pnmh = (NMHDR *) lParam;
            int nMessage = pnmh->code;

            if (nMessage == TCN_SELCHANGE)
            {
                  TRACE("Tab Selection Changed!");
                  int nSel = GetTabCtrl().GetCurSel( );
                  if (m_VwList.GetSize() == 0)
                  {
                        TRACE("ERROR: CTabView::OnChildNotify nSel = %d, m_vwViewList size = %d\n",nSel, m_VwList.GetSize());
                        if (message != WM_DRAWITEM)
                              return CCtrlView::OnChildNotify(message, wParam, lParam, pResult);
                  
                        ASSERT(pResult == NULL);
                        UNUSED(pResult);

                        DrawItem((LPDRAWITEMSTRUCT)lParam);
                  }

                  if (nSel != m_nActiveTab)
                  {
                        BOOL bShowResult;
                        int nOldView = m_nActiveTab;
                        m_nLastActiveTab = nOldView;
                        m_nActiveTab = nSel;
                        
                        LockWindowUpdate( );

                        bShowResult = ((CWnd*)(m_VwList[nOldView]))->ShowWindow(SW_HIDE);
                        bShowResult = ((CWnd*)(m_VwList[nSel]))->ShowWindow(SW_SHOW);
                        
                        CRect rViewRect;
                        GetChildRect(rViewRect);
                        UnlockWindowUpdate();
                        RedrawWindow( rViewRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOERASE );
                  }
            }
      }
      if (message != WM_DRAWITEM)
            return CCtrlView::OnChildNotify(message, wParam, lParam, pResult);

      ASSERT(pResult == NULL);
      UNUSED(pResult);

      DrawItem((LPDRAWITEMSTRUCT)lParam);
      return TRUE;
}

void CTabView::OnInitialUpdate()
{
      m_bCreated = FALSE;
      CCtrlView::OnInitialUpdate();

   // Create the font to use for the tabs
      CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();

      m_pFont = new CFont;
      m_pFont->CreateFont(14,0,0,0,500,0,0,0,
            ANSI_CHARSET,OUT_TT_PRECIS,
            CLIP_TT_ALWAYS,DEFAULT_QUALITY,
            VARIABLE_PITCH|FF_SWISS,
            "arial");

      ctlTab.SetFont( m_pFont );
      m_bCreated = TRUE;
}

void CTabView::OnDraw(CDC* pDC)
{
      // TODO: Add your specialized code here and/or call the base class
      CDocument* pDoc = GetDocument();
      
}

BOOL CTabView::OnEraseBkgnd(CDC* pDC)
{
      if (m_VwList.GetSize() > 0)
      {
            CTabCtrl& ctlTab = (CTabCtrl&) GetTabCtrl();
            
            // Get rectangle enclosing the whole tab control
            CRect rCntrlRect;
            GetClientRect(rCntrlRect);
            
            // Account for clipping where part of the window is offscreen
            CRect rClipRect;
            pDC->GetClipBox(rClipRect);
            
            // Get the intersection of control rect and the clip rect
            rCntrlRect &= rClipRect;

            // Get the intersection of the clip rect and the contained view rect
            CRect rViewRect;
            GetChildRect(rViewRect);
            rViewRect &= rClipRect;
            
            CRgn rgnUpdateRgn;
            CRgn rgnTempRgn;
            
            // merge all to a region to paint...
            rgnUpdateRgn.CreateRectRgn(0,0,0,0);
            rgnTempRgn.CreateRectRgn( 0,0,0,0 );

            rgnUpdateRgn.SetRectRgn(rCntrlRect);
            rgnTempRgn.SetRectRgn(rViewRect);

            rgnUpdateRgn.CombineRgn( &rgnUpdateRgn, &rgnTempRgn, RGN_DIFF );
            rgnTempRgn.DeleteObject();
            
            COLORREF clr3DFace = (COLORREF) ::GetSysColor(COLOR_3DFACE);
            CBrush brshBkBrush(clr3DFace);
            
            // Paint it and delete the region...
            pDC->FillRgn(&rgnUpdateRgn, &brshBkBrush);
            rgnUpdateRgn.DeleteObject();

            return TRUE;
      }
      else
            return CCtrlView::OnEraseBkgnd(pDC);
}

void CTabView::OnSize(UINT nType, int cx, int cy)
{
      CCtrlView::OnSize(nType, cx, cy);
      
      // TODO: Add your message handler code here

      TRACE("CTabView::OnSize called\n");
      int nTabCount = GetTabCount();

      if ((nTabCount != 0) & (m_bCreated == TRUE))
      {
            CRect rViewRect(0,0,0,0);
            BOOL bResult = GetChildRect(rViewRect);

            if (rViewRect.Width() == 0)
                  m_rOldRect = CRect(0,0,0,0);
            else
            {
                  for (int nCounter = 0; nCounter < nTabCount; nCounter++)
            ((CWnd*) (m_VwList[nCounter]))->MoveWindow(rViewRect);
                  UpdateWindow();
                  m_rOldRect = rViewRect;
            }
            m_bSizing = TRUE;
      }
      
}

void CTabView::OnSysColorChange()
{
      CCtrlView::OnSysColorChange();
      m_ctlImage.SetBkColor(GetSysColor(COLOR_3DFACE));
}

Commented:
Have you emailed me of given me your email address so I can send you more samples?

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.