안녕하세요.
3번째 시간입니다.
지난번 글보시고, VirtualTreeView 의 도움말중 Step by Step 이란 장을 미리 보시분들은
글의 순서가 똑갔네 ^^ 하고 생각하시는 분들오 있을듯하네요.
제가 참조한 것도 그것이라 비슷할 것입니다.
이번시간에는
폼에 VirtualTreeView 를 올려 놓고, 컬럼 3개를 추가해서
각 컬럼에 데이타를 넣어주는 것을 해 보겠습니다.
VirtualTreeView 를 사용할 때에는 먼저 내가 무슨 데이타를 가지고 화면에 어떻게 보여줄 것인지 먼저
고민 하셔야 합니다.
제가 3개의 컬럼을 가진 VirtualTreeView 를 리스트 형태로 보이는 것으로 하겠습니다.
1. 데이타할 구조체를 만들자
VirtualTreeView 는 지난번에도 말씀 드렸지만, 데이타 저장 공간을 VTV (VirtualTreeView )가 할당해주고,
우리는 이것을 사용하고,
사용이 끝나면 VTV 가 해제를 해 주는 구조라고 하였습니다.
그러므로, 제일 먼저할 일은 내가 필요한 데이타의 구조체를 만들 어 주는 것입니다.
Class로 하면 안되냐구요?
위에서도 이야기 했지만 우리가 new를 하지 않습니다. Class 로 만들고 new없이 사용할 때 어떤 문제가 생길까요?
저도 모르지요 ^^ 원하시는 분은 해 보세요. 단 모든 책임은 본인이.... ^^
typedef struct tagPhonebook {
AnsiString Name;
AnsiString Tel;
AnsiString Sex;
} structPhonebook, *ptrstructPhonebook;
위처럼 구조체를 선언했습니다.
Column0 -> 이름
Column1 -> 전화번호
Column2 -> 성별
이렇게 출력하려고 합니다.
지나번 강좌에서 말씀 드렸지만, Node 데이타는 할 줄(Row)에 대한 데이타 모두를 담을 수 있도록 만들어야 합니다.
각 셀별로 따로 관리 하는 것이 아닙니다.
2. 컬럼을 추가 하자
보통 컬럼이 하나라면 이 작업을 꼭 해주어야 할 필요는 없지만, 컬럼을 추가해 주어야 할 수 있는 기능들이 있기 때문에 컬럼을 추가하는 것을 권장합니다.
폼위에 TVirtualStringTree 콤포넌트를 하나 올려 놓으시구요.
Obejct Inspector 에서 Properties 를 보시면,
Header -> Columns
항목이있습니다. 여기에서 오른쪽의 [...] 이라는 버튼을 누르면 컬럼을 추가 하는 윈도우가 나옵니다.
윈도우가 나오면, 왼쪽 상단의 추가하는 버튼을 누러서 Column을 추가하여
순서대로 Text 속성에
이름 , 전화번호, 성별
을 넣어 줍니다.
첨부한 그림의 첫번째 것입니다.
그런다음에 윈도우을 닫습니다.
어! VirtualTreeView 는 똑같네요. 컬럼 추가한거 어디 갔지?
VirtualTreeView 는 header보이는 것도 속성에서 조절하기 때문에 속성을 바꾸어 줄때까지는 안 보입니다.
Header -> Options -> hoVisible
값을 true로 바꾸시면, 헤더가 보이게 됩니다.
3. 내가 사용할 데이타의 크기를 VirtualTreeView 에 알려 주자.
다시한번 말씀 드리지만, 데이타의 할당/해제 VTV가 한다고 하였잖아요.
그럼, VTV가 할당하여야할 데이타의 크기를 알아야 하잖아요.
그래서 꼭 해주서야 하는 것이 이 작업입니다.
데이타의 크기를 할려주는 방법은 2가지가 있는데요.
노드의 크기가 고정인 경우와 가변인 경우가 다릅니다.
고정인 경우는 Properties 에 보시면, NodeDataSize 란 것이 있습니다.
여기에 크기를 넣어 주시면 됩니다.
그런데 사실 데이타 크기를 손으로 계산에서 여기 써 넣을 일은 없겠지요 ^^
VirtualStringTree1.NodeDataSize = sizeof(structPhonebook);
이런식으로 넣어 주시면 됩니다. 트리가 사용되기 전에...
또다른 방법은 Events 중에 OnGetNodeDataSize 를 구현해 주는 것입니다.
이것에 가변크기일때 사용하는 방법이지만, 고정 일때 사용해도 상관없겠지요.
void __fastcall TForm1::VirtualStringTree1GetNodeDataSize(
TBaseVirtualTree *Sender, int &NodeDataSize)
{
NodeDataSize = sizeof(structPhonebook);
}
위 두 코드는 동일한 동작을 합니다만 전 주로 두번째 코드로 만듭니다 ^^
4. 데이타를 VTV 의 셀에 출력하자
다음으로 하셔야 할 것이 자신이 추가한 데이타가 VTV의 각 셀(혹은 Column) 에 출력되도록 하여야 합니다.
이것은 OnGetText 란 이벤트를 구현해 주면 됩니다.
void __fastcall TForm1::VirtualStringTree1GetText(TBaseVirtualTree *Sender,
PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType,
WideString &CellText)
{
if (!Node)
return;
structPhonebook *pPhonebook = (structPhonebook *)Sender->GetNodeData(Node);
switch (Column)
{
case 0:
CellText = pPhonebook->Name;
break;
case 1:
CellText = pPhonebook->Tel;
break;
case 2:
CellText = pPhonebook->Sex;
break;
}
}
위와 같이 메소스들 구현하면 되는데요.
Node 란 파라미터는 출력할 Node의 포인터가 옵니다.
이것은 NULL 아닌지 확인 먼저 하시구요.
NULL 이 아니면, GetNodeData(Node); 메소드를 사용하면, 해당 노드에 할당되어 있는 데이타의 포인터를
돌려 줍니다. 이것을 우리가 사용할 구조체 포인터로 넣어 주시면 됩니다.
Column 파라미터는 출력할 컬럼의 번호을 알려 줍니다.
즉 Column 번호가 0 이면 이름을 , 1이면 전화번호, 2이면 성별을 출력하도록 하였습니다.
여기 까지가 최소한 구현해 주어야 할 메쏘드 들이구요.
이제야 사용할 준비가 된 것입니다.
이제는 실제 데이타를 넣어주면 됩니다.
5. 데이타를 넣자 ^^
데이타를 넣는 방법은 다시 한번 이야기 하지만 VirtualTreeView 한테 데이타 넣을 공간을 할당해줘
하고 요청한 후에 공간이 할당되면 그곳에 데이타를 넣어 주면 됩니다.
해제는 언제 하나구요. VirtualTreeView 가 알아서 해 주므로 신경 안 쓰셔도 됩니다.
데이타를 넣는 방법은
PVirtualNode AddChild(PVirtualNode Parent, void *UserData = NULL);
이 함수를 이용해서 넣어 줍니다.
즉, AddChild 를 호출하면 , 노드하나 만들어줘 하고 VTV에 요청하는 것입니다.
이것이 돌려 주는 것이 PVirtualNode 란 Node의 포인터 이구요.
이 Node 포인터를 GetNodeData 에 넘겨주면 실제 저장할 곳의 포인터를 돌려 줍니다.
예제에서는 버튼을 하나 만들구요. 버튼을 누를 때마다 노드를 추가하는 것으로 하였습니다.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PVirtualNode Node;
structPhonebook *pPhonebook;
Node = VirtualStringTree1->AddChild(NULL);
if (Node)
{
pPhonebook = (structPhonebook *)VirtualStringTree1->GetNodeData(Node);
pPhonebook->Name = "볼레롱";
pPhonebook->Tel = "02-1234-5678";
pPhonebook->Sex = "남자";
}
}
위 소스 보시면, 아시겠지요 ^^
AddChild 로 노드 추가 하고,
그 노드에서 데이타 저장위치 가져오고,
그 저장위치에 실제 데이타 넣어 주구요.
* 오늘 강좌는 여기 까지 입니다.
첨부한 파일에 소스와 실행파일 모두가 있구요.
이거 실행 하신 후에 헤더를 Drag&Drop 해서 컬럼의 순서를 바꾸어 보세요 ^^
기본기능으로 제공합니다.
|
일반 리스트와 뭔가 다른 동작이 있을 겁니다.
VTV 속성을 바꾸면서 리스트와 동일하게 동작하도록 바꾸어 보세요 ^^
예를 들면, 선택이 라인 전체로 되게 한다던가....