☆하늘을 보쟈☆ | 미야
http://blog.naver.com/ratmsma/40012501600
선택된 아이템을 삭제할 때,
맴버 변수를 m_ctrTree라고 만들자(Control형 하나밖에 없다).
http://blog.naver.com/ratmsma/40012501600
//아이콘 가져오기
m_Image=new CImageList;
m_Image->Create(16,16,ILC_COLOR4,3,3);
m_Image->Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_Image->Add(AfxGetApp()->LoadIcon(IDI_ICON2));
//트리에 설정
m_tree.SetImageList(m_Image,TVSIL_NORMAL);
//노드추가
HTREEITEM hLevel1,hLevel2;
hLevel1=m_tree.InsertItem(treename1[0],0,1);
//함수의 반환값 HTREEITEM으로 노드를 추가할 수 있다.
for(int i=0;i<2;i++){
hLevel2=m_tree.InsertItem(treename2[i],0,1,hLevel1);
for(int j=0;j<3;j++){
m_tree.InsertItem(treename3[i][j],0,1,hLevel2);
}
// m_tree.Expand(hLevel2,TVE_EXPAND); //확장 함수
}
// m_tree.Expand(hLevel1,TVE_EXPAND);
//아이템 선택시 선택된 아이템 알아보기 : TVN_SELCHANGED메시지
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hTreeItem = pNMTreeView->itemNew.hItem; // 이 값이 선택된 아이템의 핸들
CString str=m_tree.GetItemText(hTreeItem);
Setwindow(str);
//or 다른 에디트 등에 넣을 수도 있다.GetDlgItem(IDC_EDIT1)->SetWindow(str);
<여기서, HTREEITEM hTreeItem변수를 Public에 놔둔다면, 다른 메시지 함수 등에서,선택된 아이템을 삭제할 때,
if(Afxmessagebox("정말 삭제할까요??",MBYESNO)==IDYES)
m_tree.DeleteItem(hTreeItem);
할 수 있다..>맴버 변수를 m_ctrTree라고 만들자(Control형 하나밖에 없다).
- 아이템 추가하기
TVINSERTSTRUCT TI; TI.hParent = TVI_ROOT; // TVI_ROOT, NULL // HTREEITEM값을 사용하면 해당하는 아이템의 자식으로 아이템이 추가된다. TI.hInsertAfter = TVI_LAST; // TVI_FIRST, TVI_LAST, TVI_SORT TI.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TI.item.iImage = 0; // Tree가 선택안되었을때 표시될 아이콘 TI.item.iSelectedImage = 1; // Tree가 선택되었을때 표시될 아이콘 TI.item.pszText = "root"; HTREEITEM hTreeItem = m_ctrTree.InsertItem(&TI); // 추가된 아이템의 HTREEITEM이 리턴된다.
- 아이템 확장하기.
m_ctrTree.Expand(hTreeItem, TVE_EXPAND);
- 아이템 선택시 선택된 아이템 알아보기
+ TVN_SELCHANGED 메시지를 사용한다.
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; HTREEITEM hTreeItem pNMTreeView->itemNew.hItem; // 이 값이 선택된 아이템의 핸들이다.
- 아이템 문자열 가져오기
CString str = m_ctrTree.GetItemText(hTreeItem);
- 아이템 개수 알아내기
int nCount = m_ctrTree.GetCount();
- 아이템 제거하기
m_ctrTree.DeleteItem(hTreeItem); // 핸들 아래단의 아이템들도 모두 제거된다.
- 현재 선택된 아이템 알아내기
HTREEITEM hTreeItem = m_ctrTree.GetSelectedItem();
- 위치로 아이템 찾기
CPoint p; GetCursorPos(&p); ::ScreenToClient(m_ctrTree.m_hWnd, &p); HTREEITEM hItem = m_ctrTree.HitTest(p);
- 아이템 확장 축소 감지
+ TVN_ITEMEXPANDED메시지를 사용한다.
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; TVITEM item; item.mask = TVIF_HANDLE; item.hItem = pNMTreeView->itemNew.hItem; m_ctrTree.GetItem(&item); // 아이템 정보를 알아낸다. if(item.state & TVIS_EXPANDED) { // 확장 } else { // 축소 }
- 아이템 아이콘 설정 변경
m_ctrTree.SetItemImage(hTreeItem, 0, 1);
- 아이템 에디트 입력중 포커스가 나갈때 입력중인 값 아이템에 적용하기
+ TVN_ENDLABELEDIT메시지를 사용한다.
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR; CEdit *pEdit = m_ctrTree.GetEditControl(); if(pEdit) { CString str; pEdit->GetWindowText(str); if(str.GetLength() > 0) { m_ctrTree.SetItemText(pTVDispInfo->item.hItem, str); } } //난 실패 했는데...-_-^씨잉........
- 이미지 리스트 설정
+ CImageList m_Image; // 32 x 16 아이콘 BITMAP 16 x 16 2개 짜리
m_Image.m_hImageList = ImageList_LoadImage( (HINSTANCE) GetWindowLong(m_hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_SMALL), 16, 2, RGB(255,255,255), IMAGE_BITMAP, LR_CREATEDIBSECTION); m_ctrTree.SetImageList(&m_Image, TVSIL_NORMAL); //난 이런 식으로 안하는데...
- 드래그 앤 드롭 사용하기
- 드래그 시작
- 트리컨트롤의 TVN_BEGINDRAG메시지 사용
CImageList *m_pTreeDragImage = NULL; // 드래그시 생성된 이미지 사용 HTREEITEM m_hDragItem = NULL; // 드래그시 처음 선택된 아이템 핸들 기억용 void CDlg::OnBegindragTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here // 드래그 이미지 생성 if(m_pTreeDragImage) m_pTreeDragImage->DeleteImageList(); m_pTreeDragImage = m_ctrTree.CreateDragImage(pNMTreeView->itemNew.hItem); // 드래그시 사용할 이미지 크기 계산 RECT rc; m_ctrTree.GetItemRect(pNMTreeView->itemNew.hItem, &rc, TRUE); // 아이콘을 포함하는 크기 // 드래그를 시작 m_pTreeDragImage->BeginDrag(0, CPoint(pNMTreeView->ptDrag.x-rc.left+16, pNMTreeView->ptDrag.y-rc.top)); // 드래그 이미지 표시 m_pTreeDragImage->DragEnter(&m_ctrTree, pNMTreeView->ptDrag); // 마우스 메시지를 잡아두고 SetCapture(); // 현재 선택된 아이템 핸들을 기억 m_hDragItem = pNMTreeView->itemNew.hItem; *pResult = 0; }
- 이동
- WM_MOUSEMOVE메시지 사용
void CDlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 드래그 중이라면 if(m_pTreeDragImage) { // 트리컨트롤 기준으로 마우스 좌표 계산 CPoint p = point; ClientToScreen(&p); ::ScreenToClient(m_ctrTree.m_hWnd, &p); // 마우스가 위치한 아이템을 검사한다.항목이 트리 뷰 항목위에 있는지 확인하고 그렇다면 항목이 밝게 표시되도록한다. HTREEITEM hItem = m_ctrTree.HitTest(p); // 밝게 표시된 부분과 현재 선택된 아이템이 틀리다면 if(hItem != m_ctrTree.GetDropHilightItem()) { // 드래그 이미지 그리기 중지 m_pTreeDragImage->DragLeave(&m_ctrTree); // 새로운 항목을 밝게 표시한다. m_ctrTree.SelectDropTarget(hItem); // 드래그 이미지를 다시 보여준다. m_pTreeDragImage->DragEnter(&m_ctrTree, p); } else { m_pTreeDragImage->DragMove(p); } } CDialog::OnMouseMove(nFlags, point); }
- 드롭
- WM_LBUTTONUP메시지 사용
void CDlg::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 드래그 중이 었다면 if(m_pTreeDragImage) { // 마우스 메시지 캡쳐 기능을 제거한다. ReleaseCapture(); // 드래그 과정을 중단한다. m_pTreeDragImage->DragLeave(&m_ctrTree); m_pTreeDragImage->EndDrag(); m_pTreeDragImage->DeleteImageList(); m_pTreeDragImage = NULL; // 일단 마지막으로 밝게 표시되었던 항목을 찾는다. HTREEITEM hTargetItem = m_ctrTree.GetDropHilightItem(); // 밝게 표시된 드롭 항목의 선택을 취소한다. m_ctrTree.SelectDropTarget(NULL); // 선택된 항목(아이템)이 있다면 if(hTargetItem) { // 선택된 아이템과 이동될 곳의 아이템이 같다면 이동할 필요가 없다. if(m_hDragItem != hTargetItem) { // 현재 자식의 부모 아이템 핸들을 구한다. HTREEITEM hParentItem = m_ctrTree.GetNextItem(m_hDragItem, TVGN_PARENT); // 이동하려는 곳이 자신이 직접속한 항목 이라면 이동할 필요가 없다. if(hParentItem != hTargetItem) { // 트리의 내용을 이동하자. MoveTreeItem(&m_ctrTree, m_hDragItem, hTargetItem); // 이동된 곳의 트리를 확장하자. m_ctrTree.Expand(hTargetItem, TVE_EXPAND); // 이미지도 확장한걸로 바꾸자 m_ctrTree.SetItemImage(hTargetItem, 1, 1); // 원본 트리의 모든 아이템이 사라졌다면 이미지 그림을 기본으로 바꾸자. HTREEITEM hItem = m_ctrTree.GetChildItem(hParentItem); if(!hItem) { m_ctrTree.SetItemImage(hParentItem, 0, 0); } } } } m_hDragItem = NULL; } CDialog::OnLButtonUp(nFlags, point); }
- 트리 항목(아이템) 이동 함수
// 아이템 데이터 이동 BOOL MoveTreeItem(CTreeCtrl *pTree, HTREEITEM hSrcItem, HTREEITEM hDestItem) { // 이동할 아이템의 정보를 알아내자. TVITEM TV; char str[256]; ZeroMemory(str, sizeof(str)); TV.hItem = hSrcItem; TV.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TV.pszText = str; TV.cchTextMax = sizeof(str); m_ctrTree.GetItem(&TV); DWORD dwData = pTree->GetItemData(hSrcItem); // 아이템을 추가 하자. TVINSERTSTRUCT TI; TI.hParent = hDestItem; TI.hInsertAfter = TVI_LAST; TI.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TI.item.iImage = TV.iImage; TI.item.iSelectedImage = TV.iSelectedImage; TI.item.pszText = TV.pszText; HTREEITEM hItem = pTree->InsertItem(&TI); pTree->SetItemData(hItem, dwData); // 현재 아이템에 자식 아이템이 있다면 HTREEITEM hChildItem = pTree->GetChildItem(hSrcItem); if(hChildItem) { // 자식 아이템이 있다면 같이 이동하자. MoveChildTreeItem(pTree, hChildItem, hItem); } // 확장 여부를 알아서 똑같이 하자. TVITEM item; item.mask = TVIF_HANDLE; item.hItem = hSrcItem; pTree->GetItem(&item); if(item.state & TVIS_EXPANDED) { pTree->Expand(hItem, TVE_EXPAND); } // 아이템을 선택하자. pTree->SelectItem(hItem); // 기존 아이템을 제거한다. pTree->DeleteItem(hSrcItem); return TRUE; } // 현재 트리의 모든 아이템 데이터 이동 BOOL MoveChildTreeItem(CTreeCtrl *pTree, HTREEITEM hChildItem, HTREEITEM hDestItem) { HTREEITEM hSrcItem = hChildItem; while(hSrcItem) { // 이동할 아이템의 정보를 알아내자. TVITEM TV; char str[256]; ZeroMemory(str, sizeof(str)); TV.hItem = hSrcItem; TV.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TV.pszText = str; TV.cchTextMax = sizeof(str); m_ctrTree.GetItem(&TV); DWORD dwData = pTree->GetItemData(hSrcItem); // 아이템을 추가 하자. TVINSERTSTRUCT TI; TI.hParent = hDestItem; TI.hInsertAfter = TVI_LAST; TI.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; TI.item.iImage = TV.iImage; TI.item.iSelectedImage = TV.iSelectedImage; TI.item.pszText = TV.pszText; HTREEITEM hItem = pTree->InsertItem(&TI); pTree->SetItemData(hItem, dwData); // 현재 아이템에 자식 아이템이 있다면 HTREEITEM hChildItem = pTree->GetChildItem(hSrcItem); // pTree->GetNextItem(hSrcItem, TVGN_CHILD); if(hChildItem) { MoveChildTreeItem(pTree, hChildItem, hItem); } // 확장 여부를 알아서 똑같이 하자. TVITEM item; item.mask = TVIF_HANDLE; item.hItem = hSrcItem; pTree->GetItem(&item); if(item.state & TVIS_EXPANDED) { pTree->Expand(hItem, TVE_EXPAND); } // 다음 아이템을 알아보자. hSrcItem = pTree->GetNextItem(hSrcItem, TVGN_NEXT); } // 기존 아이템을 제거한다. pTree->DeleteItem(hChildItem); return TRUE; }
- 드래그 시작
- 트리컨트롤의 TVN_BEGINDRAG메시지 사용
댓글
댓글 쓰기