Creating a CTabCtrl Application

Environment: VC6 SP3, NT4, Windows 2000 Pro, Windows 2000 Server

Firstly add the CMyTabCtrl.cpp and CMyTabCtrl.h to your project.

Using Visual Studio add a CTabCtrl control to your dialog. Add a member variable for this control as a CMyTabCtrl type not a simple CTabCtrl. CMyTabCtrl is derived from CTabCtrl.

You can simply add a CTabCtrl member variable and manually edit the file to become CMyTabCtrl

Now create dialogs for every page you require. These must be child dialogs with no border. Any controls here in these dialogs are handled by their own class.

Create a Class for each dialog. In the example these are CTabOne, CTabTwo and CTabThree.

In the CmyTabCtrl constructor you must add a new for each page. Also in the Init function you must specify all tab dialogs to hide all but one

In this example the OnLButtonDown message handler is used to show and hide the various dialogs. The page is managed with a variable m_tabCurrent which holds the value of selected pages.

In the main app dialogs OnInitDialog message handler add the tabs you require for your dialog. In this example these are Tab One, Tab Two and Tab Three.

Functionality for the left and right cursor keys to select the tabs can be added in the CMyTabCtrl class.

CMyTabCtrl::CMyTabCtrl()
{
 m_tabPages[0]=new CTabOne;
 m_tabPages[1]=new CTabTwo;
 m_tabPages[2]=new CTabThree;

 m_nNumberOfPages=3;
}

CMyTabCtrl::~CMyTabCtrl()
{
 for(int nCount=0; nCount < m_nNumberOfPages; nCount++){
  delete m_tabPages[nCount];
 }
}

void CMyTabCtrl::Init()
{
 m_tabCurrent=0;

 m_tabPages[0]->Create(IDD_TAB_ONE, this);
 m_tabPages[1]->Create(IDD_TAB_TWO, this);
 m_tabPages[2]->Create(IDD_TAB_THREE, this);

 m_tabPages[0]->ShowWindow(SW_SHOW);
 m_tabPages[1]->ShowWindow(SW_HIDE);
 m_tabPages[2]->ShowWindow(SW_HIDE);

 SetRectangle();
}

void CMyTabCtrl::SetRectangle()
{
 CRect tabRect, itemRect;
 int nX, nY, nXc, nYc;

 GetClientRect(&tabRect);
 GetItemRect(0, &itemRect);

 nX=itemRect.left;
 nY=itemRect.bottom+1;
 nXc=tabRect.right-itemRect.left-1;
 nYc=tabRect.bottom-nY-1;

 m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
 for(int nCount=1; nCount < m_nNumberOfPages; nCount++){
  m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
 }
}


//////////////////////////////////////////////////////
// CMyTabCtrl message handlers

void CMyTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
 CTabCtrl::OnLButtonDown(nFlags, point);

 if(m_tabCurrent != GetCurFocus()){
  m_tabPages[m_tabCurrent]->ShowWindow(SW_HIDE);
  m_tabCurrent=GetCurFocus();
  m_tabPages[m_tabCurrent]->ShowWindow(SW_SHOW);
  m_tabPages[m_tabCurrent]->SetFocus();
 }
}

The Dialog Showing, Hiding and Drawing code is from the C++ Forum On this site. It was posted by someone whom I don't have name for.

If it was you then please let me know and I will have your name added

I hope this code is of some use. It has helped me to develop much more complex dialogs.

Downloads

Download demo project - 18 Kb
Download source - 2 Kb


Comments

  • typo?

    Posted by Swiss Frank on 05/22/2013 07:18am

    nY=itemRect.bottom+1; I think you meant: - 1

    Reply
  • Bad example if you want to access Controls from different Tabs

    Posted by hoschy on 07/18/2006 05:36am

    It works quite nice, BUT I want to access lets say a editcontrol in one tab from the main dialog, its just not possible. ItB4s better to use the main Dialog for Initialization and stuff, this way you can access all editcontrols in the main Dialog. And this is what most users want i think.

    Reply
  • Resolution to Strange behaviour on keypress

    Posted by ksumit on 04/09/2004 04:11am

    All that needs to be done is add OnCancel() event handlers for all the child dialogs/forms.And within this get the Parent dialog pointer and distroy the dialog. For key press (enter) have an event handler OnOK for each child dialogs.

    Reply
  • Another way to get data from Tab to Main Dialog

    Posted by pkpk on 03/31/2004 07:15pm

    I ran across this on Google Groups it works well: In your tab class code use the following line to get a hook to the main dialogs member variables and functions CMyTabExampleDlg* pMainWnd = (CMyTabExampleDlg*) AfxGetMainWnd(); pMainWnd will then give you access to main dialog

    Reply
  • Strange behaviour on keypress (enter-/esc key)

    Posted by Stoodent on 03/26/2004 09:06am

    If you put the focus to any control whithin the tab area so that the OK or CANCEL button is not selected and you hit the enter key the tab page will disappear. I think that the reason for this is that WM_ERASEBKGND will be sent to the child window (tab page) without a WM_PAINT after the key has been pressed. I don't think it is a good way just to ignore any WM_ERASEBKGND messages by implementing WindowProc(...), so does anybody know a better solution ?

    • RE: Strange behaviour on keypress (enter-/esc key)

      Posted by JOC_Consulting on 12/18/2009 06:05pm

      I noticed the same problem of the Enter/Esc key causing the tab page dialog to disappear. According to the "Property Sheet as the View Window of a CFrameWnd" article at http://support.microsoft.com/kb/161886 , the reason is that the Enter and Esc keys, in MFC, are normally routed to OnOK and OnCancel, respectively. This article includes sample code that shows not only how to deal with the Enter and Esc keys, but also how to implement using Ctrl + Tab to go to the next tab page and Shift + Ctrl + Tab to go the previous tab page. My application has only 2 tabs so it hard to tell for sure, but this code seems to work properly.

      Reply
    • RE:- Strange behaviour on keypress (enter-/esc key)

      Posted by LalitSRana on 04/22/2005 01:42am

      You can think of changing this behaviour by blocking these two keys.
      
      BOOL CDeltaLOCDlg::PreTranslateMessage(MSG* pMsg) 
      {
      	// TODO: Add your specialized code here and/or call the base class
      	
      	if(pMsg->message==WM_KEYDOWN)
      	{
      		if(pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE)
      			pMsg->wParam=NULL ;
      	} 
      	
      	return CDialog::PreTranslateMessage(pMsg);
      }

      Reply
    Reply
  • Select a tab programmatically

    Posted by Legacy on 12/08/2003 12:00am

    Originally posted by: Richard

    Firstly, many thanks to Ben Hill for showing me how to use the Tab Control. Like Alexis Giotis I also want to select a tab programmatically. Eventually I worked out how to do it by adding the another member function

    void SelectTab(int nextTab);

    to the CMyTabCtrl class declaration and the following definition

    void CMyTabCtrl::SelectTab(int nextTab)
    {
    SetCurFocus(nextTab);
    if(m_tabCurrent != GetCurFocus()){
    m_tabPages[m_tabCurrent]->ShowWindow(SW_HIDE);
    m_tabCurrent=GetCurFocus();
    m_tabPages[m_tabCurrent]->ShowWindow(SW_SHOW);
    m_tabPages[m_tabCurrent]->SetFocus();
    }
    }

    However, I can only get this to work when it is added after the line
    m_tabMyTabCtrl.Init();
    in CMyTabExampleDlg::OnInitDialog() which, although it can be used to change the initial tab, it is not what I want.

    If I use, say, m_tabMyTabCtrl.SelectTab(2); in another class (associated with a Check dialog with code in a TabCheck.cpp file) then I get an error message on compilation indicating that m_tabMyTabCtrl is not a class. I think that I have included all of the appropriate .h files in the .cpp file.

    This is all tied up with file scope. Please be kind to me as this is only my second C++ program! Although I am an experienced Fortran, Visual Basic programmer, C is new to me (and I am struggling).

    Reply
  • Very cool but!

    Posted by Legacy on 11/20/2003 12:00am

    Originally posted by: Karim

    I have studied your code, and implemented it sucessfully in a dialog however...

    I am writing a control panel applet, and when used, none of the controls in the 'sub' dialogs seem to get focus or have the ability to respond when clicked.

    I personally belive this has somthing to do with implementing this code in a dll however, I am not sure. Any ideas?

    Thanks
    Karim

    • Change parent?

      Posted by Sam Hobbs on 03/26/2004 08:21pm

      I think the parent of the dialogs for the tabs is supposed to be the same parent as the tab control; that is not logical but Windows is not always logical. In this sample, the parent is the tab control.

      Reply
    Reply
  • Lose menu bar...

    Posted by Legacy on 10/02/2003 12:00am

    Originally posted by: Rico

    Hi All,

    When I use this tab control, it will make my menu bar at the button disappear.
    Is there any way to fix it?

    Many Thanks,
    Rico

    Reply
  • Problem with tab in the bottom and the "&"-sign

    Posted by Legacy on 08/21/2003 12:00am

    Originally posted by: Kenn

    Very great job with the tabcontrol, but one minor problem I can't fix.
    If you move the tabs to the bottom, everything is great, except when you add an "&"-sign anywhere in your text. The moment you press the specific tab, the text bumps up a bit. It looks a bit silly.

    Anyone know how to fix this ?

    Best regards, Kenn

    Reply
  • Application Die

    Posted by Legacy on 08/17/2003 12:00am

    Originally posted by: chris

    I wonder anybody encountered this problem before.
    
    

    I had create a main Dialog with a button that will show a sub dialog when click.

    I create the tabControl in this sub Dialog. The funny thing is; I had no problem with one tab link to a child dialog. Problem occur when I try to add more tabs link to more child dialogs. The application die everytime I try to access the sub dialog. Worst, there is no error msg. I don't know where to trace my problem. Can somebody out there assist me?

    Thanks a million in advance.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The latest release of SugarCRM's flagship product gives users new tools to build extraordinary customer relationships. Read an in-depth analysis of SugarCRM's enhanced ability to help companies execute their customer-facing initiatives from Ovum, a leading technology research firm.

  • Instead of only managing projects organizations do need to manage value! "Doing the right things" and "doing things right" are the essential ingredients for successful software and systems delivery. Unfortunately, with distributed delivery spanning multiple disciplines, geographies and time zones, many organizations struggle with teams working in silos, broken lines of communication, lack of collaboration, inadequate traceability, and poor project visibility. This often results in organizations "doing the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds