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

C++빌더 강좌/문서
C++Builder Programming Tutorial&Docments
[61] [강좌] VirtualTreeView #3 : 최소 구현 예제
볼레롱 [bolero] 20023 읽음    2005-06-17 11:16
columns.jpg 29.6KB 컬럼 추가된 화면
phonebook.zip 482.4KB 소스및 실행파일
안녕하세요.

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 해서  컬럼의 순서를 바꾸어 보세요 ^^
기본기능으로 제공합니다.
볼레롱 [bolero]   2005-06-17 11:32 X
이거 실행해 보시고,

일반 리스트와  뭔가 다른 동작이 있을 겁니다.
VTV 속성을 바꾸면서 리스트와 동일하게 동작하도록 바꾸어 보세요 ^^

예를 들면,  선택이 라인 전체로 되게 한다던가....
볼레롱 [bolero]   2005-06-18 13:43 X
참 빠진것이 있는데요.

첨부한 파일의 가져다가 빌드할때 ,
[C++ Error] uxtheme.h(546): E2146 Need an identifier to declare

이런 에러가 나오는 수가 있는데요.
이것은  테마메니져에서 사용하는 헤더 파일이 더 새 버전이라서 그렇거든요.

C:\Program Files\Soft Gems\Theme Manager\CBuilder
이 디렉토리의 readme.txt 파일 보시면 되는데,

결론은 MS의 플랫폼 SDK 에 들어 있던 헤더파일인데,
BCB 배포후에 변경되었으니까  헤더파일 대치해 주라는 이야기 입니다.

C:\Program Files\Soft Gems\Theme Manager\CBuilder
위 디렉토리에서

Uxtheme.h


C:\Program Files\Borland\CBuilder6\Include
이 디렉토리에 복사해 주시면 됩니다.

다른 헤더파일도 이런 에러나오면 교체해 주시면 됩니다.
황경록 [mpbox]   2005-06-20 16:43 X
좋은 내용 감사드립니다. __*
김태선 [jsdkts]   2005-12-11 23:35 X
Uxtheme.h 헤더파일 교환해주어도 되지만
에러나는 부분의 typedef 을 /*typedef*/ 주석처리해도 됩니다.

+ -

관련 글 리스트
61 [강좌] VirtualTreeView #3 : 최소 구현 예제 볼레롱 20023 2005/06/17
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.