Solved

tab control for multiple views

Posted on 1997-05-14
3
545 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
Comment Utility
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
Comment Utility
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
Comment Utility
Have you emailed me of given me your email address so I can send you more samples?

0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

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…
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.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

772 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

11 Experts available now in Live!

Get 1:1 Help Now