Tree Control
트리 컨트롤은 탐색기에서 많이 볼 수 있다. 여기서는 트리 컨트롤의 기본적인 기능인 아이템의 추가, 수정, 삭제, 선택, 확장에 대해서 배우도록 한다.
1. 트리 컨트롤의 기본 구조
트리 컨트롤은 아래와 같이 하나의 아이템에 하나의 TVITEM 구조체로 나타낸다. 여러 아이템들이 있을 때 리스트 컨트롤에서는 LVITEM의 iItem과 iSubItem으로 구분하였지만, 트리 컨트롤에서는 TVITEM의 hItem으로 각각 구분한다. HTREEITEM은 트리컨트롤의 각각의 아이템의 핸들값이다. TVITEM 구조체를 살펴보면 다음과 같다.
typedef struct tagTVITEM{
UINT mask;
HTREEITEM hItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
LPARAM lParam;
} TV_ITEM, FAR *LPTVITEM;
그리고 아이템을 추가할 때에 아래와 같은 TVINSERTSTRUCT라는 구조체를 쓴다. 이 구조체는 아이템을 추가할 곳을 설정한다.
typedef struct tagTVINSERTSTRUCT {
HTREEITEM hParent;
HTREEITEM hInsertAfter;
TVITEM item;
} TV_INSERTSTRUCT, FAR *LPTVINSERTSTRUCT;
HTREEITEM
Handle to an item in a tree-view control.
hParent
Handle to the parent item. If this member is the TVI_ROOT value or NULL, the item is inserted at the root of the tree view control.
hInsertAfter
Handle to the item after which the new item is to be inserted, or one of the following
TVI_FIRST Inserts the item at the beginning of the list.
TVI_LAST Inserts the item at the end of the list.
TVI_SORT Inserts the item into the list in alphabetical order.
item
TVITEM structure that contains information about the item to add.
2. 이 장에서 사용하게 될 트리 컨트롤의 멤버 함수
멤버 함수 |
기능 |
InsertItem |
새로운 아이템을 추가한다. |
DeleteItem |
지정된 아이템을 지운다. |
SetItem |
아이템의 정보를 설정한다. |
GetItem |
아이템의 정보를 얻는다. |
GetItemText |
각각 아이템의 텍스트를 얻는다. |
SetImageList |
각각 아이콘으로 사용될 이미지 리스트를 설정한다. |
Select |
지정된 아이템을 선택한다. |
Expand |
지정된 아이템을 확장한다. |
3. Microsoft Visual C++을 구동한 후, New Project에서 MFC AppWizard (Exe) 선택하고 Name명에 MyApp를 친 다음 OK한다. Dialog Based를 선택하고 Finish버튼을 한다.
4. 폼 디자인
Control IDs |
Name |
Category |
Variable type |
IDC_TREE |
m_TreeCtrl |
Control |
CTreeCtrl |
IDC_SELECTEDITEM |
m_hItem |
Value |
CString |
IDC_CHECKBOX |
m_bRoot |
Value |
BOOL |
위와 같이 디자인을 한 후, Tree Control을 선택하여 오른쪽 마우스 버튼이 누르고 Properties를 선택하면 창이 하나 뜬다. Styles에서 Has buttons, Has lines, Lines at root, Show selection always를 체크한다.
5. 멤버 함수 추가
Control IDs |
Message |
Member Function Name |
IDC_TREE |
TVN_SELCHANGED |
OnSelchangedTree |
IDC_ADDITEM |
BN_CLICKED |
OnAdditem |
IDC_MODIFYITEM |
BN_CLICKED |
OnModifyitem |
IDC_DELETEITEM |
BN_CLICKED |
OnDeleteitem |
6. 트리 컨트롤의 초기화 코딩
트리 컨트롤의 기본적인 아이템들을 추가하고, 이미지 리스트 설정하는 부분이다. 아이콘 2개를 추가한다. ID명을 IDI_OPENSMALLICON와 IDI_SMALLICON라는 하고, 16×16의 크기로 만든다.
클래스 CMyAppDlg의 헤드 파일에 CImageList m_smallImageList; 선언을 추가하고, 다음 내용을 추가 한다.
BOOL CMyAppDlg::OnInitDialog()
{
CDialog::OnInitDialog();
.....
// TODO: Add extra initialization here
// ImageList Initialization & Tree Control Attach // 아이콘 등록
m_SmallImageList.Create(16, 16, ILC_COLORDDB | ILC_MASK, 4, 4); // 설명 추가
m_SmallImageList.Add(AfxGetApp()->LoadIcon(IDI_SMALLICON));
m_SmallImageList.Add(AfxGetApp()->LoadIcon(IDI_OPENSMALLICON));
m_TreeCtrl.SetImageList(&m_SmallImageList, TVSIL_NORMAL);
char *data[4][10] = {
{"동물", "원숭이", "호랑이", "사자", "토끼", NULL},
{"자동차", "포니", "사피아", "그랑죠", "브루샤", NULL},
{"꽃", "장미", "백합", "할미꽃", "민들레", "개나리", NULL},
{"로보트", "그렌다이저", "마징가", "태권브이", "건담", NULL}
};
TVINSERTSTRUCT tvins;
TVITEM tvi;
HTREEITEM hItem;
for (int i = 0; i < 4; i++)
{
for (int j = 0; data[i][j]; j++)
{
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvi.pszText = data[i][j];
tvi.iImage = 0;
tvi.iSelectedImage = 1;
tvins.hInsertAfter = TVI_LAST;
tvins.item = tvi;
if (j == 0)
{
tvins.hParent = TVI_ROOT;
hItem = m_TreeCtrl.InsertItem(&tvins);
}
else
{
tvins.hParent = hItem;
m_TreeCtrl.InsertItem(&tvins);
}
}
}
return TRUE; // return TRUE unless you set the focus to a control
}
7. 추가 버튼 코딩
추가 버튼을 눌렀을 때 아이템을 추가한다. 만약에 "루트에 추가"라는 체크박스를 체크하고 추가를 하면 루트에 추가되고, 체크하지 않고 추가하면 선택된 아이템의 하위 아이템으로 추가된다. 추가 버튼을 눌렀을 때 아이템을 추가만 처리하는 것이 아니라 아이템을 확장하고 선택되는 것까지 처리한다.
void CMyAppDlg::OnAdditem()
{
UpdateData();
TV_INSERTSTRUCT tvins;
TV_ITEM tvi;
HTREEITEM hItem, hInsItem;
hItem = m_TreeCtrl.GetSelectedItem();
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvi.pszText = (LPTSTR)(LPCTSTR)m_hItem;
tvi.iImage = 0;
tvi.iSelectedImage = 1;
tvins.hInsertAfter = TVI_LAST;
tvins.item = tvi;
if (m_bRoot)
{
tvins.hParent = TVI_ROOT;
hInsItem = m_TreeCtrl.InsertItem(&tvins);
m_TreeCtrl.Select(hInsItem, TVGN_CARET);
}
else
{
tvins.hParent = hItem;
hInsItem = m_TreeCtrl.InsertItem(&tvins);
m_TreeCtrl.Expand(hItem, TVE_EXPAND); // 아이템 확장
m_TreeCtrl.Select(hInsItem, TVGN_CARET); // 아이템 선택
}
}
8. 수정 버튼 코딩
수정은 에디트 컨트롤 IDC_SELECTEDITEM에 문자열을 입력하고 수정 버튼을 누르게 되면 해당 아이템이 바뀌게 된다.
void CMyAppDlg::OnModifyitem()
{
UpdateData();
TV_ITEM tvi;
HTREEITEM hItem = m_TreeCtrl.GetSelectedItem();
tvi.mask = TVIF_HANDLE;
tvi.hItem = hItem;
m_TreeCtrl.GetItem(&tvi);
tvi.mask |= TVIF_TEXT;
tvi.pszText = (LPTSTR)(LPCTSTR)m_hItem;
m_TreeCtrl.SetItem(&tvi);
}
9. 삭제 버튼 코딩
삭제는 선택된 아이템을 얻어서 DeleteItem을 호출하여 삭제한다. 만약에 선택된 아이템이 없다면 무시된다.
void CMyAppDlg::OnDeleteitem()
{
HTREEITEM hItem = m_TreeCtrl.GetSelectedItem();
if (hItem != NULL && MessageBox("삭제하겠습니까?", NULL, MB_YESNO |
MB_ICONQUESTION) == IDYES)
m_TreeCtrl.DeleteItem(hItem);
}
10. 아이템을 선택할 때 에디트 컨트롤에 나타내기
아이템을 선택하였을 때 선택된 아이템의 텍스트를 읽어서 에디트 컨트롤에 나타낸다. 위에서 IDC_TREE에서 TVN_SELCHANGED라고 메시지로 멤버 함수 OnSelchangedTree라는 멤버 함수를 추가하였다. 이 부분을 편집하자.
void CMyAppDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
m_hItem = m_TreeCtrl.GetItemText(hItem);
UpdateData(FALSE);
*pResult = 0;
}
'프로그래밍 > C++' 카테고리의 다른 글
구조체(struct)와 공용체(union) (0) | 2009.12.02 |
---|---|
트리컨트롤(TreeCtrl) 사용법 종합 (0) | 2009.11.08 |
More Effective C++ 요약정리 (0) | 2009.11.02 |
Effective c++ 인터넷문서 (0) | 2009.11.01 |
VC++ 자료형 외 표현범위 (0) | 2009.10.30 |
댓글