Solved

tab control for multiple views

Posted on 1997-05-14
3
558 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
0
Comment
Question by:kbb
  • 3
3 Comments
 
LVL 10

Accepted Solution

by:
RONSLOW earned 100 total points
ID: 1301565
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.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1301566
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));
}

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1301567
Have you emailed me of given me your email address so I can send you more samples?

0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
MFC Dialog 9 49
function returning CString in a regular win32 DLL 8 178
zeroFront challenge 7 99
Making an alias 7 95
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question