www.pudn.com > superlistctrl.rar > MySuperGrid.cpp


// MySuperGrid.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "supergrid.h" 
#include "MySuperGrid.h" 
#include "ComboInListView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CMySuperGrid 
 
CMySuperGrid::CMySuperGrid() 
{ 
} 
 
CMySuperGrid::~CMySuperGrid() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CMySuperGrid, CSuperGridCtrl) 
	//{{AFX_MSG_MAP(CMySuperGrid) 
	ON_WM_CREATE() 
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMySuperGrid message handlers 
 
int CMySuperGrid::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CSuperGridCtrl::OnCreate(lpCreateStruct) == -1) 
		return -1; 
 
	///////////////////// 
	//remember this	 
	/////////////////// 
 
	//associate imagelist with listviewctrl	 
	if(!m_image.Create(IDB_FOLDERS,16,1,RGB(0, 255, 255))) 
		return -1; 
	 
	SetImageList(&m_image,LVSIL_SMALL); 
	CImageList *pImageList = GetImageList(LVSIL_SMALL); 
	if(pImageList) 
		ImageList_GetIconSize(pImageList->m_hImageList, &m_cxImage, &m_cyImage); 
	else 
		return -1; 
	 
	return 0; 
} 
 
 
void CMySuperGrid::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
	if(pNMListView->iSubItem ==0) 
	{ 
		CTreeItem *pRoot = GetRootItem(); 
		if(pRoot!=NULL) 
		{		 
			Sort(pRoot, TRUE);			 
			//do a simple refresh thing 
			if(ItemHasChildren(pRoot)) 
			{ 
				SetRedraw(0); 
				Collapse(pRoot); 
				Expand(pRoot, 0); 
				SetRedraw(1); 
			} 
		} 
	} 
 
	*pResult = 0; 
} 
 
 
 
void CMySuperGrid::InitializeGrid() 
{ 
	/* 
	ExtendedStyle support: 
	LVS_EX_TRACKSELECT 
	LVS_EX_GRIDLINES 
	LVS_EX_FLATSB 
	LVS_EX_CHECKBOXES 
	all other ExStyles are not supported...buhhh and you call your self a windows-developer :( 
	*/ 
	#if _MSC_VER >= 1200 
	SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FLATSB/*|LVS_EX_CHECKBOXES*/); 
	#else 
	IE4StyleEx(LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES);  
	#endif 
	 
	LPTSTR lpszCols[] = {_T("Tree thing"),_T("Column #1"),_T("Column #2"),_T("Column #3"),_T("Column #4"),0}; 
	LV_COLUMN   lvColumn; 
	//initialize the columns 
	lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
	lvColumn.fmt = LVCFMT_LEFT; 
	lvColumn.cx = 200; 
	for(int x = 0; lpszCols[x]!=NULL; x++) 
    { 
		//make the secondary columns smaller 
		if(x) 
		  lvColumn.cx = 150; 
 
		lvColumn.pszText = lpszCols[x]; 
		InsertColumn(x,&lvColumn); 
    } 
	 
	int nCol = GetNumCol(); 
 
 
	CItemInfo* lp = new CItemInfo(); 
	//add item text 
	lp->SetItemText(_T(""));  
	//add subitem text 
	lp->AddSubItemText(_T("Happy"));      // 0 zero based subitems... 
	lp->AddSubItemText(_T("Programming"));// 1 
	lp->AddSubItemText(_T("with this"));  // 2 
	lp->AddSubItemText(_T("SuperGrid"));  // 3 combo goes here 
 
 
	//Create root item 
	if(!CreateTreeCtrl(lp)) 
		return; 
	 
	//insert items	 
	for(int i=0; i < nCol; i++) 
	{ 
		CItemInfo* lpItemInfo = new CItemInfo(); 
		CString strItem; 
		strItem.Format(_T("HHItem %d"),i); 
		//add items text 
		lpItemInfo->SetItemText(strItem); 
		//add subitem text 
		for(int y=0;y < nCol-1; y++)  
		{ 
			CString str; 
			str.Format(_T("subItem %d of %s"),y,lpItemInfo->GetItemText()); 
			lpItemInfo->AddSubItemText(str); 
		} 
		//insert the iteminfo with ParentPtr 
		CTreeItem* pParent = InsertItem(GetRootItem(), lpItemInfo); 
		//other nodes 
		 
		 
		CTreeItem* pParent1=NULL; 
		for(int x=0; x < nCol; x++) 
		{ 
			CItemInfo* lpItemInfo = new CItemInfo(); 
			CString strItem; 
			strItem.Format(_T("Item %d"),x); 
			lpItemInfo->SetItemText(strItem); 
			for(int z=0; z < nCol-1; z++)  
			{ 
				CString str; 
				str.Format(_T("subItem %d of %s"),z, lpItemInfo->GetItemText()); 
				lpItemInfo->AddSubItemText(str); 
			} 
			pParent1 = InsertItem(pParent, lpItemInfo); 
			 
		} 
 
	 
	} 
 
	//could now expand one level 
	Expand(GetRootItem(), 0 /*listview index 0*/);  
	UINT uflag = LVIS_SELECTED | LVIS_FOCUSED; 
	SetItemState(0, uflag, uflag); 
} 
 
 
//helper function to copy CItemInfo used when drag/drop you must override this this function to suit your own CItemInfo class 
CItemInfo* CMySuperGrid::CopyData(CItemInfo* lpSrc) 
{ 
	ASSERT(lpSrc!=NULL); 
	CItemInfo* lpDest = new CItemInfo; 
	lpDest->SetItemText(lpSrc->GetItemText()); 
	lpDest->SetCheck(lpSrc->GetCheck()); 
	for(int nCol=0; nCol < lpSrc->GetItemCount(); nCol++) 
	{ 
		CString str = lpSrc->GetSubItem(nCol); 
		lpDest->AddSubItemText(str); 
		//if any control type are assoc with the CItemInfo 
		CItemInfo::CONTROLTYPE ctrlType; 
		if(lpSrc->GetControlType(nCol, ctrlType))//true if other than edit-control 
		{ 
			lpDest->SetControlType(ctrlType, nCol); 
			//assume list control...but you should explict test on the ctrlType(combobox,listbox, your control...); 
			CStringList *list=NULL; 
			list = lpSrc->GetListData(); 
			if(list!=NULL) 
				lpDest->SetListData(list);	 
		} 
	} 
	return lpDest; 
} 
 
//override, like red! 
COLORREF CMySuperGrid::GetCellRGB() 
{ 
	return RGB(192,0,0); 
} 
 
 
//this is my override of GetIcon, override this to set what ever icon suits you 
int CMySuperGrid::GetIcon(const CTreeItem* pItem) 
{ 
	CItemInfo *pData=GetData(pItem); 
    if(pData->GetItemText()==_T("Bugs: Impossible")) 
		return 3;//image index 3 trash can 
 
	int iImage = 0; 
	if(ItemHasChildren(pItem)) 
	{ 
		IsCollapsed(pItem) ? iImage = 1/*close icon*/:iImage = 0;/*open icon*/ 
	} 
	else 
		iImage = 2;//doc icon 
 
	return iImage; 
} 
 
 
 
//override 
void CMySuperGrid::OnUpdateListViewItem(CTreeItem* lpItem, LV_ITEM *plvItem) 
{ 
	//put some extra validation here  
	CString str = (CString)plvItem->pszText; 
	if(!str.Compare(_T("Bugs: Impossible"))) 
	{ 
		str+=_T(" (selfconfidence allright)");//that's valid enough	:§) 
		CItemInfo *lp = GetData(lpItem); 
		if(lp!=NULL) 
		{ 
			if(plvItem->iSubItem==0) 
				lp->SetItemText(str); 
			else //subitem data  
				lp->SetSubItemText(plvItem->iSubItem-1, str); 
		   UpdateData(lpItem, lp); //update internal nodes 
		} 
		SetItemText(plvItem->iItem, plvItem->iSubItem, str.GetBuffer(1)); 
	} 
	else 
		CSuperGridCtrl::OnUpdateListViewItem(lpItem, plvItem); 
} 
 
/* 
	if I ever wanted to update a (sub)item at runtime with no user input 
 
	LV_ITEM lvItem; 
	lvItem.iItem= what ever Item; 
	lvItem.iSubItem = what ever subitem; 
	lvItem.pszText = "what ever text"; 
    CTreeItem *lpItem = GetTreeItemFromSomeWhere_AndMakeSureItsNotCollapsed_E_G_MustBeVisible(); 
	//if node not visible mayby do a SelectNode(lpItem); here 
	m_List.OnUpdateListViewItem(lpItem, &lvItem);	 
*/ 
 
 
//override called when OnLButtondown 
void CMySuperGrid::OnControlLButtonDown(UINT nFlags, CPoint point, LVHITTESTINFO& ht) 
{ 
	//now I am sure I added a combobox some where, so check for this control 
	CTreeItem*pSelItem = reinterpret_cast(GetItemData(ht.iItem)); 
	if(pSelItem!=NULL) 
	{	 
		CItemInfo* pInfo = GetData(pSelItem); 
		CItemInfo::CONTROLTYPE ctrlType; 
		if(pInfo->GetControlType(ht.iSubItem-1, ctrlType)) 
		{	 
			if(ctrlType==pInfo->CONTROLTYPE::combobox)  
			{ 
					CStringList* list=NULL; 
					list = pInfo->GetListData(); 
					CComboBox * pList = ShowList(ht.iItem, ht.iSubItem, list); 
			} 
		}								 
		/* 
		else //activate default edit control 
			CSuperGridCtrl::OnControlLButtonDown(nFlags, point, ht); 
		*/ 
	} 
} 
 
 
//override 
BOOL CMySuperGrid::PreTranslateMessage(MSG* pMsg)  
{ 
	if(pMsg->message == WM_KEYDOWN) 
	{ 
		if(GetFocus()==this) 
		{ 
			switch( pMsg->wParam ) 
			{ 
				case VK_RETURN: 
					{ 
						int iItem = GetNextItem( -1, LVNI_ALL | LVNI_SELECTED); 
						if( GetCurSubItem() != -1 && iItem != -1) 
						{ 
							CTreeItem*pSelItem = reinterpret_cast(GetItemData(iItem)); 
							if(pSelItem!=NULL) 
							{	 
								CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0); 
								int iSubItem = Header_OrderToIndex(pHeader->m_hWnd, GetCurSubItem()); 
								 
								CItemInfo* pInfo = GetData(pSelItem); 
								CItemInfo::CONTROLTYPE ctrlType; 
								if(pInfo->GetControlType(iSubItem-1, ctrlType)) 
								{	 
									switch(ctrlType) 
									{ 
										/*put in your own control here*/ 
										case pInfo->CONTROLTYPE::datecontrol:break; 
										case pInfo->CONTROLTYPE::spinbutton:break; 
										case pInfo->CONTROLTYPE::dropdownlistviewwhatevercontrol:break; 
										case pInfo->CONTROLTYPE::combobox:  
											{ 
 
												CStringList* list=NULL; 
												list = pInfo->GetListData(); 
												CComboBox * pList = ShowList(iItem, iSubItem, list); 
												return 1; //I'll handle it from here 
											}break; 
										default:break; 
									} 
								} 
							} 
						} 
				} 
				break; 
			} 
		} 
	} 
	return CSuperGridCtrl::PreTranslateMessage(pMsg); 
} 
 
 
 
 
#define IDC_COMBOBOXINLISTVIEW 0x1235 
CComboBox* CMySuperGrid::ShowList(int nItem, int nCol, CStringList *lstItems) 
{ 
	CString strFind = GetItemText(nItem, nCol); 
 
	//basic code start 
	CRect rect; 
	int offset = 0; 
	// Make sure that the item is visible 
	if( !EnsureVisible(nItem, TRUE)) return NULL; 
 
	#if _MSC_VER >= 1200 
		GetSubItemRect(nItem, nCol, LVIR_BOUNDS, rect); 
	#else 
		// Get the column offset 
		for( int i = 0; i < nCol; i++ ) 
			offset += GetColumnWidth(i); 
		GetItemRect( nItem, &rect, LVIR_BOUNDS ); 
	#endif 
	// Now scroll if we need to expose the column 
	CRect rcClient; 
	GetClientRect(rcClient); 
	if( offset + rect.left < 0 || offset + rect.left > rcClient.right ) 
	{ 
		CSize size; 
		size.cx = offset + rect.left; 
		size.cy = 0; 
		Scroll(size); 
		rect.left -= size.cx; 
	} 
	 
	rect.left += offset;	 
	rect.right = rect.left + GetColumnWidth(nCol); 
	if(rect.right > rcClient.right)  
	   rect.right = rcClient.right; 
	//basic code end 
 
	rect.bottom += 10 * rect.Height();//dropdown area 
	 
	DWORD dwStyle =  WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL|CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL; 
	CComboBox *pList = new CComboInListView(nItem, nCol, lstItems); 
	pList->Create(dwStyle, rect, this, IDC_COMBOBOXINLISTVIEW); 
	pList->ModifyStyleEx(0,WS_EX_CLIENTEDGE);//can we tell at all 
	pList->SetHorizontalExtent(CalcHorzExtent(pList, lstItems)); 
	pList->ShowDropDown(); 
	pList->SelectString(-1, strFind.GetBuffer(1)); 
	// The returned pointer should not be saved 
	return pList; 
} 
 
 
 
int CMySuperGrid::CalcHorzExtent(CWnd* pWnd, CStringList *pList) 
{ 
	int nExtent=0; 
	if(pWnd!=NULL) 
	{ 
		CDC* pDC = pWnd->GetDC(); 
		HFONT hFont = (HFONT)pWnd->SendMessage(WM_GETFONT); //why not pWnd->GetFont();..I like the send thing alot and 
		CFont *pFont = CFont::FromHandle(hFont);			//this way I get to use this function..cool :) 
		if(pFont!=NULL)										//ya what ever makes me happy,.right :} 
		{ 
			CFont* pOldFont = pDC->SelectObject(pFont); 
			CSize newExtent; 
			POSITION pos = pList->GetHeadPosition(); 
			while(pos != NULL) 
			{ 
				CString str(pList->GetNext(pos)); 
				newExtent = pDC->GetTextExtent(str); 
				newExtent.cx += 6; 
				if (newExtent.cx > nExtent) 
				{ 
					nExtent = newExtent.cx; 
				} 
			} 
			pDC->SelectObject(pOldFont); 
		} 
		pWnd->ReleaseDC(pDC); 
	} 
	return nExtent; 
} 
 
 
//HOWTO:  
void CMySuperGrid::HowToInsertItemsAfterTheGridHasBeenInitialized(int nIndex, const CString& str) 
{ 
	CTreeItem *pSelItem = reinterpret_cast(GetItemData(nIndex)); 
	if(pSelItem!=NULL) 
	{ 
		SetRedraw(0); 
		BOOL bUpdate=FALSE; 
		if(!IsCollapsed(pSelItem)) 
			bUpdate=TRUE;//children are expanded, want to see update right away if not no visual update 
 
		CItemInfo* lpRelative = new CItemInfo; 
		lpRelative->SetItemText(str); 
		lpRelative->AddSubItemText(_T("I am")); 
		lpRelative->AddSubItemText(_T("now")); 
		lpRelative->AddSubItemText(_T("going to insert")); 
		lpRelative->AddSubItemText(_T("some items")); 
 
		CTreeItem* pParent = InsertItem(pSelItem, lpRelative, bUpdate); 
		for(int i=0; i < GetNumCol(); i++) 
		{ 
			CItemInfo* lpItemInfo = new CItemInfo; 
			CString strItem; 
			strItem.Format(_T("Item %d"), i); 
			//add items text 
			lpItemInfo->SetItemText(strItem); 
			//add subitem text 
			for(int y=0;y < GetNumCol()-1; y++)  
			{ 
				CString str; 
				str.Format(_T("subItem %d of %s"), y, lpItemInfo->GetItemText()); 
				lpItemInfo->AddSubItemText(str); 
				//set combobox in last col 
				lpItemInfo->SetControlType(lpItemInfo->CONTROLTYPE::combobox, GetNumCol()-2/*zero based, remember*/); 
				CStringList list; 
				for(int x=0; x<10;x++) 
				{ 
					CString str; 
					str.Format("listitem %d",x); 
					list.AddTail(str); 
				} 
				lpItemInfo->SetListData(&list); 
			} 
			InsertItem(pParent, lpItemInfo); 
		} 
		SetRedraw(1); 
		InvalidateRect(NULL); 
		UpdateWindow(); 
	} 
} 
 
 
 
void CMySuperGrid::HowToLoopThroughAllItems_if_we_wanted_to_print_them_or_what_ever(CDC *pDC) 
{ 
	TEXTMETRIC tm; 
	pDC->GetTextMetrics(&tm); 
	int cy = tm.tmHeight + tm.tmExternalLeading; 
	int nLineY=0; 
	nLineY+=cy; 
 
	pDC->TextOut(10, nLineY, _T("GIVE ME A BREAK YOU KNOW PRINT PREVIEW IS NOT THE ISSUE HERE")); 
	nLineY+=cy; 
	nLineY+=cy; 
	int nIndex = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED); //print from current node 
	if(nIndex!=-1) 
	{ 
		//GetHeadPosition 
		CTreeItem *pParent = reinterpret_cast(GetItemData(nIndex)); 
		CTreeItem *pItem = pParent; 
		CItemInfo* lp = GetData(pParent); 
 
		CString strData = lp->GetItemText(); 
		strData+='\t'; 
		nLineY+=cy; 
		for(int nCol=0; nCol < lp->GetItemCount(); nCol++) 
		{ 
			CString str = lp->GetSubItem(nCol); 
			strData+=str; 
			strData+='\t'; 
		}	 
		pDC->TabbedTextOut(10,nLineY,strData,strData.GetLength(), 0, NULL, 0); 
		nLineY+=cy; 
		//GetNext ....loop through all children  
		for(;;) 
		{ 
			CTreeItem *pCur= GetNextSiblingItem(pItem, TRUE, FALSE/*regardless of the item are hidden or not*/);	   
			if(!IsChildOf(pParent, pCur)) 
				break; 
			else 
			if(pCur==pItem) 
				break; 
 
			CItemInfo* lp = GetData(pCur); 
			CString strData = lp->GetItemText(); 
			strData+='\t'; 
			for(int nCol=0; nCol < lp->GetItemCount(); nCol++) 
			{ 
				CString str = lp->GetSubItem(nCol); 
				strData+=str; 
				strData+='\t'; 
			}	 
			pDC->TabbedTextOut(10,nLineY,strData,strData.GetLength(), 0, NULL, 0); 
			nLineY+=cy; 
			pItem=pCur; 
		} 
	 } 
} 
 
 
 
void CMySuperGrid::HowToLoopThroughAllItems_that_has_a_checkmark_and_print_them_or_what_ever(CDC *pDC) 
{ 
	TEXTMETRIC tm; 
	pDC->GetTextMetrics(&tm); 
	int cy = tm.tmHeight + tm.tmExternalLeading; 
	int nLineY=0; 
	nLineY+=cy; 
 
	pDC->TextOut(10,nLineY,_T("GIVE ME A BREAK YOU KNOW PRINT PREVIEW IS NOT THE ISSUE HERE")); 
	nLineY+=cy; 
	nLineY+=cy; 
	if(!GetItemCount()) 
		return; 
	int nIndex=0;//has to be the root  
	if(nIndex!=-1) 
	{ 
		//do a GetHeadPosition 
		CTreeItem *pParent = reinterpret_cast(GetItemData(nIndex)); 
		CTreeItem *pItem = pParent; 
		CItemInfo* lp = GetData(pParent); 
		if(lp->GetCheck())//very hard :)= 
		{ 
			CString strData=lp->GetItemText(); 
			strData+='\t'; 
			nLineY+=cy; 
			for(int nCol=0; nCol < lp->GetItemCount(); nCol++) 
			{ 
				CString str = lp->GetSubItem(nCol); 
				strData+=str; 
				strData+='\t'; 
			}	 
			pDC->TabbedTextOut(10,nLineY,strData,strData.GetLength(), 0, NULL, 0); 
			nLineY+=cy; 
		} 
		//GetNext ....loop through all children  
		for(;;) 
		{ 
			CTreeItem *pCur = GetNextSiblingItem(pItem, TRUE, FALSE/*regardless of the item are hidden or not*/);	   
			if(!IsChildOf(pParent, pCur)) 
				break; 
			else 
			if(pCur==pItem) 
				break; 
			CItemInfo* lp = GetData(pCur); 
			if(lp->GetCheck()) 
			{ 
				CString strData = lp->GetItemText(); 
				strData+='\t'; 
				for(int nCol=0; nCol < lp->GetItemCount(); nCol++) 
				{ 
					CString str = lp->GetSubItem(nCol); 
					strData+=str; 
					strData+='\t'; 
				}	 
				pDC->TabbedTextOut(10,nLineY,strData,strData.GetLength(), 0, NULL, 0); 
				nLineY+=cy; 
			} 
			pItem=pCur; 
		} 
	 } 
} 
 
 
//HOWTO: Search nodeptr that have a specific item and subitems also shows you how to select the node and delete it 
void CMySuperGrid::HowToSearch_I_am_using_hardcoded_values_here_cause_I_am_tired_now(void) 
{ 
 
	//one Item and two Subitems 
	CTreeItem *pNode =	Search(__T("Hello World"),_T("Happy"),_T("Programming"),NULL); 
	 
	if(pNode!=NULL) 
	{ 
		CItemInfo *pInfo = GetData(pNode); 
		AfxMessageBox(_T("Found Item ") + pInfo->GetItemText()); 
	} 
	else AfxMessageBox(_T("not found")); 
	//one Item and one Subitem 
	CTreeItem *pNode1 = Search(_T("Mission: Impossible"),_T("Allan Nielsen"),NULL); 
	if(pNode1!=NULL) 
	{ 
		CItemInfo *pInfo = GetData(pNode1); 
		AfxMessageBox(_T("Found Item ") + pInfo->GetItemText()); 
 
	} 
	else AfxMessageBox(_T("not found")); 
	 
	//one Item and one Subitem 
	CTreeItem *pNode2 = Search(_T("Training Agent"),_T("Mr. Bean"),NULL); 
	if(pNode2!=NULL) 
	{ 
		CItemInfo *pInfo = GetData(pNode2); 
		AfxMessageBox(_T("Found Item") + pInfo->GetItemText()); 
	} 
	else AfxMessageBox(_T("not found")); 
 
	CTreeItem *pNode3 = Search(_T("BC"),NULL); 
	if(pNode3!=NULL) 
	{ 
		CItemInfo *pInfo = GetData(pNode3); 
		AfxMessageBox(_T("Found Item ") + pInfo->GetItemText()); 
		int nIndex = SelectNode(pNode3); 
		if(nIndex!=-1) 
		if(AfxMessageBox(_T("Do you want to delete it"),MB_OKCANCEL)==IDOK) 
			DeleteItemEx(pNode3, nIndex); 
	} 
	else AfxMessageBox(_T("not found")); 
 
	CTreeItem *pItem = SearchEx(GetRootItem(), "AB"); 
	if(pItem!=NULL) 
	{ 
		CItemInfo *pInfo = GetData(pItem); 
		AfxMessageBox(_T("Found Item ") + pInfo->GetItemText()); 
		int nIndex = SelectNode(pItem); 
		if(nIndex!=-1) 
		if(AfxMessageBox(_T("Do you want to delete it"),MB_OKCANCEL)==IDOK) 
			DeleteItemEx(pItem, nIndex); 
	} 
	else AfxMessageBox(_T("not found")); 
 
 
} 
 
 
 
//this is just one way to search items...strItem must match and then all subitems must be 
//a match before returning the node 
//the search function here search all nodes regardless if collapsed or expanded 
CMySuperGrid::CTreeItem* CMySuperGrid::Search(CString strItem,...) 
{ 
 
	if(!GetItemCount()) 
		return NULL; 
 
	va_list args; 
	va_start(args, strItem); 
	int nCount=0; 
	 
	for(;;) 
	{ 
		LPCTSTR lpsz = va_arg(args, LPCTSTR); 
		if(lpsz==NULL) 
			break; 
	   nCount++; 
	} 
	 
	CTreeItem *pParent = GetRootItem(); 
	CTreeItem *pItem = pParent; 
	CItemInfo* lp = GetData(pParent); 
	CString strData = lp->GetItemText(); 
	if(strData==strItem)//must be a match before going further...suit you self 
	{ 
		va_start(args, strItem); 
		int nResult=0; 
		for(int i=0; iGetItemCount(); nCol++) 
			{ 
				CString str = lp->GetSubItem(nCol); 
				if(!str.CompareNoCase(lpsz)) 
				{ 
					nResult++; 
					break; 
				} 
			}	 
		} 
		va_end(args); 
		if(nCount==nResult)//all args was found return node 
			return pParent; 
	} 
 
	//GetNext ....loop through all children  
	for(;;) 
	{ 
		CTreeItem *pCur = GetNextSiblingItem(pItem, TRUE, FALSE/*regardless of the item are hidden or not, set to TRUE if only visible items must be included in the search*/);	   
		if(!IsChildOf(pParent, pCur)) 
			break; 
		else 
		if(pCur==pItem) 
			break; 
		CItemInfo* lp = GetData(pCur); 
		CString strData = lp->GetItemText(); 
		if(strData==strItem)//must be a match before going further 
		{ 
			va_start(args, strItem); 
			int nResult=0; 
			for(int i=0; iGetItemCount(); nCol++) 
				{ 
					CString str = lp->GetSubItem(nCol); 
					if(!str.CompareNoCase(lpsz)) 
					{ 
						nResult++; 
						break; 
					} 
				}	 
			} 
			va_end(args); 
			if(nCount==nResult)//all args was found return node 
				return pCur; 
		} 
		pItem=pCur;//next; 
	} 
	return NULL; 
} 
 
 
void CMySuperGrid::SortData() 
{ 
	int nIndex = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);  
	if(nIndex==-1) 
		return; 
 
	CTreeItem *pItem = reinterpret_cast(GetItemData(nIndex)); 
 
	if(AfxMessageBox("Sort all children(Yes)\nor just sort rootitems(No)",MB_YESNO)==IDYES) 
		Sort(pItem, TRUE);			 
	else 
		Sort(pItem, FALSE);			 
	//do a simple refresh thing 
	if(ItemHasChildren(pItem)) 
	{ 
		SetRedraw(0); 
		Collapse(pItem); 
		Expand(pItem, nIndex); 
		SetRedraw(1); 
	} 
} 
 
 
 
//another search thing 
CMySuperGrid::CTreeItem* CMySuperGrid::SearchEx(CTreeItem *pStartPosition, CString strItem) 
{ 
	CItemInfo* lp = GetData(pStartPosition); 
	//if(lp->GetCheck()) another condition here maybe 
	CString strData = lp->GetItemText(); 
	if(strData==strItem) 
	{ 
		return pStartPosition; 
	} 
 
	const int nChildren = NumChildren(pStartPosition); 
	if (nChildren > 0) 
	{ 
		POSITION pos = GetHeadPosition(pStartPosition); 
		while (pos) 
		{ 
			CTreeItem *pChild = GetNextChild(pStartPosition, pos); 
			CItemInfo* lp = GetData(pChild); 
			CString strData = lp->GetItemText(); 
			if(strData==strItem) 
			{ 
				return pChild; 
			} 
		} 
	} 
 
	POSITION pos = GetHeadPosition(pStartPosition); 
	while (pos) 
	{ 
		CTreeItem *pChild = GetNextChild(pStartPosition, pos); 
		CItemInfo* lp = GetData(pChild); 
		CString strData = lp->GetItemText(); 
		if(strData==strItem) 
		{ 
			return pChild; 
		} 
 
		pChild = SearchEx(pChild, strItem); 
		if(pChild!=NULL) 
			return pChild; 
	} 
	return NULL; 
}