Adding Items to a Tree View Control

You can add items to a tree view control by sending the TVM_INSERTITEM message or by calling the associated TreeView_InsertItem macro. In MFC, use the InsertItem member function. For each item, you must fill out the TV_ITEM and TV_INSERTSTRUCT structures. When adding an item, you must specify the handle of the new item's parent item. If you specify NULL or TVI_ROOT instead of an item handle, the item is added as a root item.

The following example demonstrates how to add items to a tree view control. This sample handles the real estate listing you saw earlier, with three houses listed for each of three cities. A global structure keeps track of the handle to the parent item and its image.

typedef struct tagHOUSEINFO
{
char szAddress [MAX_ADDRESS];
int iImage;
HTREEITEM hParent;
} HOUSEINFO;

BOOL AddTreeViewItems (HWND hwndTree)
{
static HTREEITEM hPrev;
char szText [MAX_LEN];
int index;

// First add the root item "Houses for Sale."
LoadString (hInst, IDS_FORSALE, szText, MAX_LEN);
hTRoot = AddOneItem ((HTREEITEM)NULL, szText, (HTREEITEM)TVI_ROOT,
idxForSale, hwndTree);

// Now add the cities.
LoadString (hInst, IDS_REDMOND, szText, MAX_LEN);
hTRed = AddOneItem (hTRoot, szText, (HTREEITEM)TVI_FIRST, idxRedmond,
hwndTree);

LoadString (hInst, IDS_BELLEVUE, szText, MAX_LEN);
hTBel = AddOneItem (hTRoot, szText, hTRed, idxBellevue, hwndTree);

LoadString (hInst, IDS_SEATTLE, szText, MAX_LEN);
hTSea = AddOneItem (hTRoot, szText, hTBel, idxSeattle, hwndTree);

// Fill out the structure for each house.
FillInStruct (hTRed, idxRedmond, 0, 3);
FillInStruct (hTBel, idxBellevue, 3, 6);
FillInStruct (hTSea, idxSeattle, 6, 9);

// Add the houses for each city.
hPrev = hTSea;
for (index = 0; index < NUM_HOUSES; index++)
{
hPrev = AddOneItem (rgHouseInfo[index].hParent,
rgHouseInfo[index].szAddress,
hPrev,
rgHouseInfo[index].iImage,
hwndTree);
rgHouseInfo[index].hItem = hPrev;
}
return TRUE;
}

// This function saves the current image and the handle to the
// parent of the tree view item.
VOID FillInStruct (HTREEITEM hParent, int iImage, int index, int iMax)
{
for (; index < iMax; index++)
{
rgHouseInfo[index].iImage = iImage;
rgHouseInfo[index].hParent = hParent;
}
}

// This function fills out the TV_ITEM and TV_INSERTSTRUCT structures
// and adds the item to the tree view control.
HTREEITEM AddOneItem (HTREEITEM hParent, LPSTR szText,
HTREEITEM hInsAfter, int iImage, HWND hwndTree)
{
HTREEITEM hItem;
TV_ITEM tvI;
TV_INSERTSTRUCT tvIns;

// The pszText, iImage, and iSelectedImage members are filled out.
tvI.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
tvI.pszText = szText;
tvI.cchTextMax = lstrlen (szText);
tvI.iImage = iImage;
tvI.iSelectedImage = iImage;

tvIns.item = tvI;
tvIns.hInsertAfter = hInsAfter;
tvIns.hParent = hParent;

// Insert the item into the tree.
hItem = (HTREEITEM) SendMessage (hwndTree, TVM_INSERTITEM, 0,
(LPARAM)(LPTV_INSERTSTRUCT)&tvIns);

return (hItem);
}

In MFCTREE, the MFC version of the TREEVIEW sample, the control is created in the view class. The preceding C code is nearly identical to the MFC code. You should note where I keep track of some of the data in MFCTREE, however. In the header file for the view class, MFCTRVW.H, the view class is defined. Within this class, I save the CTreeCtrl object, the image list, the indexes to the images associated with the tree view items, and information about the item being dragged.

class CMfctreeView : public CView
{
protected: // create from serialization only
CMfctreeView();
DECLARE_DYNCREATE(CMfctreeView);
CTreeCtrl m_TreeCtl; // tree view control
CImageList m_ImageList; // image list associated with tree
BOOL m_fDragging; // whether you are dragging an item
HTREEITEM m_hDragItem; // current item being dragged
int m_idxForSale; // index to For Sale icon
int m_idxRedmond; // index to Redmond icon
int m_idxBellevue; // index to Bellevue icon
int m_idxSeattle; // index to Seattle icon

// Attributes
public:
CMfctreeDoc *GetDocument ();

// Operations
public:
BOOL AddTreeViewItems ();
HTREEITEM AddOneItem (HTREEITEM, LPSTR, HTREEITEM, int);
VOID FillInStruct (HTREEITEM, int, int, int);
VOID BeginDrag (NM_TREEVIEW *);
VOID DropItem (HTREEITEM);

// Overrides
// ClassWizard generated virtual function overrides.
// {{AFX_VIRTUAL (CMfctreeView)
public:
virtual void OnDraw (CDC *pDC); // overridden to draw this
// view
protected:
virtual LRESULT WindowProc (UINT message, WPARAM wParam,
LPARAM lParam);
// }}AFX_VIRTUAL

// Implementation
public:
virtual ~CMfctreeView ();

protected:

// Generated message map functions
protected:
// {{AFX_MSG (CMfctreeView)
afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize (UINT nType, int cx, int cy);
afx_msg void OnDestroy ();
afx_msg void OnMouseMove (UINT nFlags, CPoint point);
afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
// }}AFX_MSG
DECLARE_MESSAGE_MAP ()
};