반응형


[퍼옴] http://blog.naver.com/PostView.nhn?blogId=fablezzg&logNo=10029762570&widgetTypeCall=true


[ 트리컨트롤(Tree Control) ]

 

1. 대화상자에 트리컨트롤을 붙이고 옵션을 다음과 같이 수정하자.



   Edit labels: 트리컨트롤에서 에디트 기능을 사용할때.

   Show selection always: 선택된 아이템을 표시할때.

 

2. 맴버 변수를 m_ctrTree라고 만들자(Control형 하나밖에 없다).

 

3. 아이템 추가하기

   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이 리턴된다.

 

4. 아이템 확장하기.

   m_ctrTree.Expand(hTreeItem, TVE_EXPAND);

 

5. 아이템 선택시 선택된 아이템 알아보기

   + TVN_SELCHANGED메시지를 사용한다.

   NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

   HTREEITEM hTreeItem = pNMTreeView->itemNew.hItem;   // 이 값이 선택된 아이템의 핸들이다.

 

6. 아이템 문자열 가져오기

   CString str = m_ctrTree.GetItemText(hTreeItem);

 

7. 아이템 개수 알아내기

   int nCount = m_ctrTree.GetCount();

 

8. 아이템 제거하기

   m_ctrTree.DeleteItem(hTreeItem);   // 핸들 아래단의 아이템들도 모두 제거된다.

 

9. 현재 선택된 아이템 알아내기

   HTREEITEM hTreeItem = m_ctrTree.GetSelectedItem();

 

10. 위치로 아이템 찾기

   CPoint  p;

   GetCursorPos(&p);

   ::ScreenToClient(m_ctrTree.m_hWnd, &p);

   HTREEITEM hItem = m_ctrTree.HitTest(p);

 

11. 아이템 확장 축소 감지

   + 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

   {

      // 축소

   }

 

12. 아이템 아이콘 설정 변경

   m_ctrTree.SetItemImage(hTreeItem, 0, 1);

 

13. 아이템 에디트 입력중 포커스가 나갈때 입력중인 값 아이템에 적용하기

   + 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);

      }

   }

 

14. 이미지 리스트 설정

   + 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);

 

 

 

 

- 드래그 앤 드롭 사용하기

 

1. 드래그 시작

   - 트리컨트롤의 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;

   }

 

2. 이동

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

   }

 

3. 드롭

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

   }

 

4. 트리 항목(아이템) 이동 함수

   // 아이템 데이터 이동

   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;

   }

[출처] [스크랩] [MFC] 트리컨트롤(Tree Control) 사용법 종합|작성자 솔로독백


반응형
Posted by tislqhf

블로그 이미지
개인적인 공부자료 정리하는 공간
tislqhf

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2025.2
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함