|
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); // 드랍될 노드의 하위 노드로 붙인다.
}
}
}
두서없는 설명이 도움이 되었는지 모르겠군요.
그럼 이만..
------------------------------------------------------
작은 생각이 세상을 바꾼다. - 정성훈.해미 -
------------------------------------------------------
정석 님이 쓰신 글 :
:
: 안녕하세요.
: 탐색기 처럼 리스트 헤더를 드래그 해서 헤더의 순서를 바꾸는 걸 구현하려고 합니다.
:
: 어떻게 해야 할지 샘플같은게 있으면 더욱 좋구요.
:
: 부탁드립니다.
|