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;
}