안녕하세요.
VirtualTreeView 의 좋은 기능 중에 하나가 부모와 자식 관계를 관리할 수 있도록 기능을 제공한다는 것입니다.
첨부한 첫번째 그럼처럼 버튼을 누를때 마다 루트노드나 자식노드를 추가하는 예제를 만들어 보겠습니다.
1. 폼에 필요 컴포넌트 가져다 놓기
이번예제는 첨부한 첫번째 그림과 같은 프로그램을 만들것인데요.
여기에서 필요한 콤포넌트는
TVirturalStringTree 1개
TImageList 1개
TButton 2개
정도를 폼에 올려 놓습니다.
그외에 위치 정렬을 위해서 Panel 같은 콤포넌트를 추가로 올릴 수도 있겠지요.
2. ImageList 에 이미지 로드
ImageList에 적당한 이미지 아무것이 2개를 추가 합니다. 1개는 루트노드를 위한 이미지이고, 다른 것은 자식노드를
위한 이미지 입니다.
3. TVirturalStringTree 의 속성 수정
TVirturalStringTree 의 속성에서
Images 에 ImageList1 를 지정합니다.
Header -> Columns
에 새로운 컬럼 1개를 추가합니다. 이것을 화면에는 보이지 않지만, Column 1개를 사용한다는 의미에서 추가합니다.
그런데, 기본으로 추가되는 Columns의 Width 가 TVirturalStringTree 의 Width와 다르기 때문에
그냥 실행하면 너무 작게 나옵니다.
이런경우 Columns의 Width 값이 TVirturalStringTree 의 Width에 맞추어서 자동으로 조절되도록 하는 속성이 있는데요.
Header -> AutoSizeIndex : 0 <-- Column 0를 기준으로 삼음
을 넣어 줍니다. 그러면 Column 0의 Width를 VTV의 전체 크기에 맞추어서 조절합니다.
4. 데이타 구조 선언
이번 예제는 Column 이 1개만 있는 VTV른 만들 것이므로, 노드 데이타 구조체는 아래와 같이 만들었습니다.
typedef struct tagNodeData {
AnsiString Value; // 노드의 값
int ImageIndex; // 출력할 이미지의 인덱스
} structNodeData;
5. 기본 메소드 구현
OnGetNodeDataSize 이벤트를 아래와 같이 구현해 줍니다.
void __fastcall TForm1::VirtualStringTree1GetNodeDataSize(
TBaseVirtualTree *Sender, int &NodeDataSize)
{
NodeDataSize = sizeof(structNodeData);
}
OnGetText 이벤트를 구현해 줍니다.
void __fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree *Sender,
PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType,
WideString &CellText)
{
if (!Node)
return;
structNodeData *pNodeData = (structNodeData *)Sender->GetNodeData(Node);
CellText = pNodeData->Value;
}
OnGetImageIndex 이벤트를 구현해 줍니다.
void __fastcall TForm1::VirtualStringTree1GetImageIndex(
TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind,
TColumnIndex Column, bool &Ghosted, int &ImageIndex)
{
if (!Node)
return;
if (Column == 0)
{
structNodeData *pNodeData = (structNodeData *)Sender->GetNodeData(Node);
ImageIndex = pNodeData->ImageIndex;
}
}
6. 노드 추가
이제 노드를 추가하는 버튼을 추가해서 버튼의 이벤트에 구현해 줍니다.
6.1. 루트노드 추가
우선 루트노드를 추가하는 버튼을 하나 만들고, 이 버튼의 이벤트에 아래와 같이 구현해 줍니다.
void __fastcall TForm1::BtnAddRootNodeClick(TObject *Sender)
{
PVirtualNode Node;
structNodeData *pNodeData;
Node = VirtualStringTree1->AddChild(NULL);
if (Node)
{
pNodeData = (structNodeData *)VirtualStringTree1->GetNodeData(Node);
pNodeData->Value = "루트노드";
pNodeData->ImageIndex = 0;
}
}
여기서 주의 깊게 보실 곳은
Node = VirtualStringTree1->AddChild(NULL);
이 부분입니다.
AddChild 에서 파라미터가 NULL로 전달되는 경우, 부모가 없는 루트노드로 노드를 생성합니다.
그 아래의 노드 데이타를 넣어주는 것은 이전과 동일하죠 ^^
ImageIndex를 루트노드는 0 번을 사용하였습니다.
6.2. 자식노드 추가
자식노드를 추가하는 것은
AddChild 에서 파라미터로 부모노드의 포인터를 넣어 주면 됩니다.
그래서 예제에서는 현재 포커스가 가 있는 노드를 부모로 해서 생성하는 예제를 만들었습니다.
void __fastcall TForm1::BtnAddChildNodeClick(TObject *Sender)
{
PVirtualNode Node;
structNodeData *pNodeData;
if (!VirtualStringTree1->FocusedNode)
return;
Node = VirtualStringTree1->AddChild(VirtualStringTree1->FocusedNode);
if (Node)
{
pNodeData = (structNodeData *)VirtualStringTree1->GetNodeData(Node);
pNodeData->Value = "자식노드";
pNodeData->ImageIndex = 1;
}
}
소스가 루트노드 생성과 거의 똑같지요.
AddChild의 파라미터가 있는 것과 노드의 데이타를 다른값을 넣어 주는 것만 다르구요.
첨부한 파일에 전체 프로젝트를 넣어 두었습니다.
한번 실행해 보시면 어렵지 않을 것입니다.
PS. VirtualTreeView를 설치 하고 처음 예제를 만들다 보면, 컴파일 에러가 나오거나
헤더파일을 못 찾는 경우가 있는데요.
이것은 project 설정에서 include와 lib 패스가 잘못 설정되어 있어서 그렇습니다.
BCB 메뉴중에
Project -> Options
에 들어 가시면
Directories/Conditionals 란 탭이 있는데요.
이곳에서 Include Path 와 Library Path 에 VritrualTreeView와 테마메니져의 Path를
추가해 주시면됩니다.
C:\Program Files\Soft Gems\Virtual Treeview\Source
C:\Program Files\Soft Gems\Theme Manager\Source
기본으로 설치하셨다면 위 두 패스를 추가하면 됩니다.
그럼!
|