C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[28937] [답변] 드래그오버, 드래그드랍 이벤트를 이용하세요.
정성훈.해미 [sage5nor] 1812 읽음    2004-02-28 14:41
TTreeView의 F1도움말을 보면 간단한 예제가 나와있습니다.
TTreeView도움말중 Event->OnDragOver(또는 OnDragDrop)의 사용법과 예제를 보면됩니다.

[구현]
1. 트리뷰의 아이템(노드)을 드래그한다.
2. 트리뷰의 드래그오버이벤트가 발생한다.-> 코드에서 드래그 할 것인지 결정해 준다.
3. 원하는 위치에 드랍한다.
4. 드래그드랍이벤트가 발생한다. -> 코드에서 드랍한 곳으로 아이템(노드)을 이동 시킨다.


아래는 제가 구현한 방법입니다.
저도 도움말 보고 혼자서 만든거라 정답은 아닙니다.

//---------------------------------------------------------------------------
//DONE: TreeView DragOver Event
void __fastcall TfmMain::TreeView1DragOver(TObject *Sender, TObject *Source,
      int X, int Y, TDragState State, bool &Accept)
{
    // 드래그를 허용 할 것인지 아닌지를 결정하는 것이 Accept입니다.
    // Accept가 true이면 드래그 허용상태가 됩니다.
    // Source는 드래그오버 이벤트가 발생한 콤포넌트(여기서는 트리뷰가 됩니다.)
    // 어떤 조건에서 드래그를 할 것인지만 결정해주면 됩니다.

    // 구현
    // 드래그할 아이템이 트리뷰의 선택된 노드이고
    // 드랍될 위치가 드래그할 아이템(선택된 노드)의 하위 노드가 아닐때
    // 드래그 가능하게 합니다.
   
   
    Accept = false; // 일단 드래그 불가로 설정.
    if(Source->InheritsFrom(__classid(TTreeView))) // 드래그할 대상이 트리뷰이면
    {
        TTreeView *pTV = (TTreeView *)Source; // 코딩을 간단하게 하기위해 포인터를 씀. 이름이 길어지면 보기 힘들어서..
        if(pTV->Selected != NULL) // 드래그 대상(트리뷰)에 선택된 노드가 있으면 (노드를 드래그 할때만 허용하고 그냥 트리뷰의 빈 공간을 드래그하면 안 먹게하기 위해)
        {
            // 아래부분은 타겟위치(드랍할 위치)가 드래그할 노드의 하위 노드인지 검사하는 부분
            // 자신의 하위 노드로 이동하면 안되게 하기위해 (거울에 다른 거울을 마주보게 하는 것과 같은 결과를 막기위해)
           
            // 드래그할 노드 아래에 있는 노드(자신의 하위는 제외)의 고정인덱스를 찾는다.
            int NextAbsoluteIndex = pTV->Selected->AbsoluteIndex+1;
            TTreeNode *pNext = pTV->Selected;
            do{
                pNext = pNext->GetNext();
                if(pNext != NULL && pNext->Level <= pTV->Selected->Level)
                {
                    NextAbsoluteIndex = pNext->AbsoluteIndex;
                    pNext = NULL;
                }
            }while(pNext != NULL);

            TTreeNode *pTarget = pTV->GetNodeAt(X, Y); // 드랍할려는 위치(끌고 간 마우스의 위치)에 있는 노드를 찾는다.
           
            // 드랍할 노드의 고정인덱스가 드래그할 노드의 하위 노드가 아니면(드래그할 노드와 위에서 감사한 인덱스의 사이에 들지 않으면)
            if(pTarget->AbsoluteIndex < pTV->Selected->AbsoluteIndex-1 ||
                      NextAbsoluteIndex <= pTarget->AbsoluteIndex)
            {
                Accept = true; // 드래그 허용
            }
        }
    }
}

//---------------------------------------------------------------------------
//DONE: TreeView DragDrop Event
void __fastcall TfmMain::TreeView1DragDrop(TObject *Sender, TObject *Source,
      int X, int Y)
{
    // 여기서는 마우스 드랍 동작때 노드를 이동해주는 부분입니다.
    // 드래그 드랍하면 대상위치의 하위노드로 이동되게 하였습니다.

    if(Source->InheritsFrom(__classid(TTreeView)))
    {
        TTreeView *pTV = (TTreeView *)Source;
        TTreeNode *pSource = pTV->Selected; // 드래그할 노드
        if(pSource != NULL)
        {
            TTreeNode *pTarget = pTV->GetNodeAt(X, Y); // 드랍될 노드
            pSource->MoveTo(pTarget, naAddChild); // 드랍될 노드의 하위 노드로 붙인다.
        }
    }
}



두서없는 설명이 도움이 되었는지 모르겠군요.

그럼 이만..

------------------------------------------------------
작은 생각이 세상을 바꾼다. - 정성훈.해미 -
------------------------------------------------------

정석 님이 쓰신 글 :
:
: 안녕하세요.
: 탐색기 처럼 리스트 헤더를 드래그 해서 헤더의 순서를 바꾸는 걸 구현하려고 합니다.
:
: 어떻게 해야 할지 샘플같은게 있으면 더욱 좋구요.
:
: 부탁드립니다.

+ -

관련 글 리스트
28928 탐색기 처럼 리스트 헤더를 드래그 해서 헤더의 순서를 바꾸는 방법? 정석 1106 2004/02/27
28937     [답변] 드래그오버, 드래그드랍 이벤트를 이용하세요. 정성훈.해미 1812 2004/02/28
34531         Re:[답변] 드래그오버, 드래그드랍 이벤트를 이용하세요. 정석 1114 2004/03/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.