Click here to Skip to main content
15,891,136 members
Articles / Desktop Programming / MFC

My Tree Control

Rate me:
Please Sign up or sign in to vote.
1.09/5 (11 votes)
10 Nov 20052 min read 66.7K   1.5K   21  
A tree control that is like a template and stores items.
#include "stdafx.h"
#include ".\Listwizard.h"
#include "NewWizDialog.h"



CListWizard::CListWizard(LPCSTR Column[],int NumOfColumns,int  RowsNum,bool HasCheckBoxes,WizItemList& GridData,void (*CallNextOnItem)(DWORD CodeID,DWORD PageID),void (*CallFinishOnItem)(DWORD CodeID,DWORD PageID),LPCSTR pTitle,LPCSTR pUpperText,HBITMAP hBitmap,int PageID,CWnd* pParent /*=NULL*/)
: CNewWizPage(CNewWizPage::IDD, pParent),
  m_HasCheckBoxes(HasCheckBoxes),
  m_RowsNum(RowsNum),
  m_SelectionMark(-1),
  m_CallNextOnItem(CallNextOnItem),
  m_CallFinishOnItem(CallFinishOnItem),
  m_Title(pTitle),
  m_hBitmap(hBitmap),
  m_UpperText(pUpperText),
  m_PageID(PageID),
  m_GridDataList(GridData)
{
	ASSERT(m_hBitmap);
	for (int i = 1;i<=NumOfColumns;++i)
	{
		m_ColumnList.push_back(Column[i-1]);
	}		
}

CListWizard::~CListWizard(void)
{
	::DeleteObject(m_hBitmap);
}
BEGIN_MESSAGE_MAP(CListWizard, CNewWizPage)

END_MESSAGE_MAP()

void CListWizard::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);


	DDX_Control(pDX, IDC_PICTURE, m_StaticPicture);
}

BOOL CListWizard::OnInitDialog()
{
	CNewWizPage::OnInitDialog();

	//picture

	m_StaticPicture.SetBitmap(m_hBitmap);

	//

	RECT DlgRect;
	CRect PictureRect;

	GetWindowRect(&DlgRect);
	CWnd* pPictureWnd = 
		GetDlgItem(IDC_PICTURE);

	if (!pPictureWnd)
	{
		MessageBox(
			"Cannot get the item's picture rectangle","Wizard 2K");
	}
	pPictureWnd->GetWindowRect(&PictureRect);
	ScreenToClient(&DlgRect);
	ScreenToClient(&PictureRect);

	CRect listRect(PictureRect.right + 18,
		PictureRect.top + PictureRect.Height()/3,
		DlgRect.right - 10,
		PictureRect.top + PictureRect.Height()*5/6);

	m_List.Create(WS_CHILD|WS_VISIBLE|WS_BORDER
		|LVS_REPORT|WS_VSCROLL|LVS_SINGLESEL|
		WS_VSCROLL|WS_TILED,
	listRect,this,1);

	m_List.SetExtendedStyle(LVS_EX_GRIDLINES|
		LVS_EX_FULLROWSELECT);

	if (m_HasCheckBoxes)
	{
		m_List.SetExtendedStyle(LVS_EX_CHECKBOXES|
			m_List.GetExtendedStyle());
	}

	
	int counter = -1;

	for (list<string>::iterator Iter = m_ColumnList.begin();
		Iter!= m_ColumnList.end();
		Iter++)
	{
		++counter;

		LVCOLUMN lv;
		lv.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
		lv.iSubItem = counter;
		lv.pszText  = (LPSTR)Iter->c_str();
		lv.cx		= 
			listRect.Width()/m_ColumnList.size();
		lv.fmt      = LVCFMT_LEFT;
		int ret = m_List.InsertColumn(counter,&lv);
	}

	for(int i = 0; i < m_RowsNum; i++)
	{
		//lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
		LV_ITEM lvi;
		lvi.mask = LVIF_TEXT|LVIF_STATE;
		lvi.iItem = i;
		lvi.iSubItem = 0;
		lvi.pszText = "default";
		//lvi.iImage = i;
		lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
		lvi.state = LVIS_SELECTED | LVIS_FOCUSED;

		m_List.InsertItem(&lvi);
		
	}

	list<pair<string,DWORD> >::iterator Iter = m_GridDataList.begin();
	for(int r = 0;r<m_RowsNum;++r)
	{
		for(int c=0;c<m_ColumnList.size();++c)
		{

			
			m_List.SetItemText(r,c,Iter->first.c_str());
			m_List.SetItemData(r,Iter->second);
			Iter++;
		}
	}
	
	m_List.SetTextBkColor(RGB(250,250,250));
	m_List.SetBkColor(RGB(250,250,250));

	m_SelectionMark = -1;

	m_List.SetSelectionMark(m_SelectionMark);
	
	m_SelectionMark = m_List.GetSelectionMark();



	return true;

}

void CListWizard::OnSetActive()
{
	m_pParent->SetTitle(m_Title.c_str());
	SetDlgItemText(ST_UPPERTEXT,m_UpperText.c_str());


	if (-1 != m_SelectionMark)
	{
		m_List.SetFocus();
	}

	m_List.SetSelectionMark(m_SelectionMark);

	int res = m_List.GetSelectionMark();
	
	m_List.RedrawWindow();
}
//true if ok
//false if not
BOOL CListWizard::OnWizardFinish()
{
	//supposed to return true in any case. if not, programmer's fault.
	//all those cases should be avoided since we're calling OnWizardCheckBeforeFinish()
	//before this function.

	//if fucked data (no selection), notify
	if (-1 == CheckSelection())
	{
		MessageBox(
			"Please select an item from the list","Wizard 2K");
	}
	//if no callback, quit!!
	else if (NULL == m_CallFinishOnItem)
	{
		return true;
	}
	//if checkbox wizard, run the callback 
	else if (m_List.GetExtendedStyle() & LVS_EX_CHECKBOXES)
	{
		int size = m_List.GetItemCount();
		//should be true to indicate there was at least
		//on check
		bool AllLoopCheck = false;
		for (int i = 0; i<size;++i)
		{
			//ID Starts at 0
			bool check = m_List.GetCheck(i);
			if (check)
			{	
				AllLoopCheck = true;
				m_CallFinishOnItem(m_List.GetItemData(i),m_PageID);
			}
		}
		return AllLoopCheck;
	}
	//no checkbox wizard, run the callback
	else
	{
		int row = m_List.GetSelectionMark();
		if (row>=0)
		{
			m_CallFinishOnItem(m_List.GetItemData(row),m_PageID);
			return true;
		}
	}
	return false;
}
//designed for "Next" page.
//return -1 if no selection, 0 if there is selection
BOOL  CListWizard::CheckSelection()
{
	if (m_List.GetExtendedStyle() & LVS_EX_CHECKBOXES)
	{
		int size = m_List.GetItemCount();

		for (int i = 1; i<=size;++i)
		{
			//ID Starts at 0
			bool check = m_List.GetCheck(i-1);
			if (check)
			{
				return 0;
			}
		}
	}
	else
	{
		int row = m_List.GetSelectionMark();
		if (row>=0)
		{
			return 0;
		}
	}
	return -1;
}

//original code returns -1 to not allow back page
//and returns 0 to allow
LRESULT CListWizard::OnWizardBack()
{
	m_SelectionMark = m_List.GetSelectionMark();
	m_List.SetSelectionMark(m_SelectionMark);

	return 0;
}

//original code returns -1 to not allow next page
//and returns 0 to allow
LRESULT CListWizard::OnWizardNext()
{
	m_SelectionMark = m_List.GetSelectionMark();
	m_List.SetSelectionMark(m_SelectionMark);
	BOOL ret = CheckSelection();
	if (-1 == ret)
	{
		MessageBox("Please select an item","Wizard 2K");
	}
	//if we should do something on next
	else if (m_CallNextOnItem)
	{	
		ASSERT(-1 != m_SelectionMark);
		m_CallNextOnItem(m_List.GetItemData(m_SelectionMark),m_PageID);
	}

	return ret;
}

//the original programmer is a beginner, using different
//return values to determine the same results...
//true is ok false isn't
BOOL CListWizard::OnWizardCheckBeforeFinish()
{
	if (-1 == CheckSelection())
	{
		MessageBox("Please select an item","Wizard 2K");
		return false;
	}

	return true;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions