Thread: (Visual C++) MFC Tree Control to do a settings page

  1. #1
    Registered User
    Join Date
    Mar 2006
    Location
    USA::Colorado
    Posts
    155

    (Visual C++) MFC Tree Control to do a settings page

    Hey,

    I'm somewhat new at MFC, so forgive me if I use incorrect terms.

    I'm trying to create a "Program Settings" dialog, which enables a user to control various settings for a program I'm making. On the left side of this dialog, there will be a Tree Control with options such as "General Settings" or "Advanced Settings", and under those will be suboptions like "Program Startup", "Settings", etc...

    On the right side of the dialog, I'd like to display different pages (aka dialogs w/o frames) that correspond to the tree. They'll have the controls that have the checkboxes and buttons that are relative to the current selected tree item. I'm sure you've all seen this done before, I'm just confused on how I can do this.


    Any help given will be greatly appreciated.


    Thanks in advance,

    Guitarist809
    ~guitarist809~

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can use a tree control on the left and then a tab control on the right. However there is some nastiness associated with the tab control in MFC. In fact there are two distinct ways I know of to create tab controls. One is to just use the default control at which point you will find it horribly inefficient and non-intuitive. These are known as property pages in MFC and the entire system is very unwieldy. The second way is to derive your own tab control and then derive your tab controls from this derived class. There is a good tutorial on this over at www.codeguru.net. I do not have the exact page but if you search on tab control I'm sure you will find it.

    I do not recommend just using the property pages as they are since it is such a mess when you want to do anything outside the realm of what the designers thought to be 'normal' usage.

  3. #3
    Registered User
    Join Date
    Mar 2006
    Location
    USA::Colorado
    Posts
    155
    Thanks for the response.

    I searched for "Tab Control" on codeguru, and I got a ton of hits. Is there another specific term that I can include to limit the unnecessary results?

    Thanks,

    Guitarist809
    ~guitarist809~

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    This is very old code so I don't exactly know the state of it. It was pulled from Codeguru and was listed as a nice way to create your own tab control that was easier to use than those provided to you.
    Last edited by VirtualAce; 03-12-2011 at 11:41 AM.

  5. #5
    Registered User
    Join Date
    Mar 2006
    Location
    USA::Colorado
    Posts
    155
    Thanks,

    I found code much like the one you provided me with, however, there is some code that I'm confused about.

    Code:
    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);
    I honestly have no clue GetClientRect and GetItemRect are doing. How do they know what tab control I'm using for this?

    (I hate using code I don't understand )

    Here's the code for the entire page:
    Code:
    // MyTabCtrl.cpp : implementation file
    //
    /////////////////////////////////////////////////////
    // This class is provided as is and Ben Hill takes no
    // responsibility for any loss of any kind in connection
    // to this code.
    /////////////////////////////////////////////////////
    // Is is meant purely as a educational tool and may
    // contain bugs.
    /////////////////////////////////////////////////////
    // [email protected]
    // http://www.shido.fsnet.co.uk
    /////////////////////////////////////////////////////
    // Thanks to a mystery poster in the C++ forum on 
    // www.codeguru.com I can't find your name to say thanks
    // for your Control drawing code. If you are that person 
    // thank you very much. I have been able to use some of 
    // you ideas to produce this sample application.
    /////////////////////////////////////////////////////
    
    #include "stdafx.h"
    #include "MyTabExample.h"
    #include "MyTabCtrl.h"
    
    #include "TabOne.h"
    #include "TabTwo.h"
    #include "TabThree.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CMyTabCtrl
    
    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);
    	}
    }
    
    BEGIN_MESSAGE_MAP(CMyTabCtrl, CTabCtrl)
    	//{{AFX_MSG_MAP(CMyTabCtrl)
    	ON_WM_LBUTTONDOWN()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // 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();
    	}
    }
    ~guitarist809~

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I'm going to be blunt here because this sort of irritates me.

    1. That is not the code I sent you.
    2. If you are going to alter source it would be a good idea if you knew how the original worked first.
    3. I'm not going to be able to help you if with the behavior of the class if you alter it from the original that I have.
    4. Breaking code and then asking for help is really not a good practice.

    The tab control really should be aggregated into an existing class. All this little class does is provide a small lightweight wrapper around CTabCtrl which made it much simpler to use - far more simpler than the alternative which is property pages.

    What I provided was a generic class and you have turned the generic class into a specific implementation with a hard coded number of pages. If you hate using code you don't understand perhaps it would be a wise idea to leave it alone and learn it before you make changes that completely change the design. AFAIK this is the exact class I pulled from CodeGuru. I'm not into the habit of altering designs just so I can understand them. If you are one who has to re-write code before you 'get it' I just cannot help you further.

    A couple of items about your 'alterations':

    • Why are you hard coding the number of pages in the constructor when there is a very clear Add function that adds any number of pages?
    • What are you going to do if you want to add more than three pages to the tab control?
    • What if upon startup you don't have 3 pages of data to stream in off the disk and yet have hard-coded 3 tabs into the class?
    • In your init function you are showing/hiding and yet there is a simple function in the class that will do this for you.
    • What if you want to show/hide a different number of pages than what you have hard-coded? Your current behavior is completely concrete and cannot change which makes the class essentially useless as a container.
    • SetRectangle() is not part of my original code and therefore I have no idea what you are trying to do
    • You've made the class harder to use and less flexible.


    My advice is to download the original code and really take a long look at it. It's not complicated and it should be easy to figure out how to use it. It did not take me long to both use and integrate it into my existing code. CodeGuru has many more MFC lightweight wrappers that greatly simplify the underlying controls. However if you break it you get to fix it.
    Last edited by VirtualAce; 08-28-2008 at 07:02 AM.

  7. #7
    Registered User
    Join Date
    Mar 2006
    Location
    USA::Colorado
    Posts
    155
    Hey,

    Sorry for taking such a while to respond. I also apologize for finding different code, you were trying to help and I ignored it .

    Anyway, If you are still interested in helping me, I was looking at the code you provided with me, and I honestly have no clue how to implement it into my code. I understand *mostly* how it works, I just cant quite get my hands around what Microsoft has written. Do I just simply create a tab control, create a class for it, and then merge the pre-created files with the ones you gave me?

    Thanks,

    Guitarist809
    ~guitarist809~

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. brace-enclosed error
    By jdc18 in forum C++ Programming
    Replies: 53
    Last Post: 05-03-2007, 05:49 PM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Messages from edit control in MFC
    By VirtualAce in forum Windows Programming
    Replies: 0
    Last Post: 01-08-2006, 01:11 AM
  5. <list>
    By Unregistered in forum C++ Programming
    Replies: 9
    Last Post: 02-24-2002, 04:07 PM