Solved

tab control for multiple views

Posted on 1997-05-14
3
553 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
ORA-01403: no data found 43 90
conditional code and condition difference 9 77
only14 challenge 19 69
Use of condition with 'serial' in ansible 2 50
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

861 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

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now