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

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[1091] [Controls] TTreeView의 Node클래스를 TTreeNode가 아닌 다른 class로 바꾸기
장성호 [nasilso] 8119 읽음    2012-06-14 20:00
음...

TreeView를 조직도 및 여러가지 데이터를 관리하고 보여주는데 많이 사용한다.



그런데 VCL에서

TTreeView의 TTreeNode에는 담을수 있는 정보에 한계가 있다.



Text
Data
ImageIndex
StateIndex
SelectedIndex

등..

Node에 보다 많은 정보를 담아야할때(( 연결해야) 할때는 어떻게 해야하나?



방법1.

  TTreeNode 클래스의 Data 프로퍼티를 활용
   일반적으로  정보는 따로 가지고 있고
   void *Data에다가 Poiner를 연결해서 많이 쓴다.

  class TMyClass 
  { 

    public: 
          String sName; 
  }; 

     
   //정보 저장   

   Node->Data = (void *) MyData; 
    
   //정보 활용 
   TMyClass *MyData=(TMyClass *)Node->Data; 
   MyData->sName;   



방법 1-1

   간단한 숫자 정보일경우
   Node->Data=(void *) iNumber ;   // 곧바로 숫자 정보를 집어 넣는다.



방법2

   또 다른 좋은 방법으로

   TTreeNode 클래스를 상속받은 Node-Class를 만들어서 Add하는 방법이 있다.



   그런데 TTreeView는 TTreeNode객체를 직접생성해서 TreeView에 Add하는 방식이 아니라

   TreeView를 통해서 객체를 생성한단.

  

바로  OnCreateNodeClass 라는 이벤트를 이용하는 것이다.

  이 이벤트에서 TTreeNode를 상속받은 class의 MetaClass를 연결해주면 된다.



간단한 샘플 코드를 작성해 보았다.

프로그램 화면




샘플 코드

다음 코드는 TTreeNode를 상속받은
TGroupNode와 TPersonNode 클래스를 TTreeView의 Node객체로 Add해서 사용한 샘플인다.


//--------------------------------------------------------------------------- 
// Group 정보를 담는 Node-Class 
//--------------------------------------------------------------------------- 
class TGroupNode : public TTreeNode 
{ 
private: 
    String FGroupName; 
    String FHints; 
        int FTag; 

public: 
    __property   String GroupName={read=FGroupName,write=FGroupName}; 
    __property   String Hints={read=FHints,write=FHints}; 
    __property   int    Tag={read=FTag,write=FTag}; 

}; 

//--------------------------------------------------------------------------- 
//개인(사람) 정보를 담는 Node-Class 
//--------------------------------------------------------------------------- 
class TPersonNode : public TTreeNode 
{ 
private: 
    String FName; 
    String FAddress; 
    String FPhoneNumber; 
    String FHints; 
        int FTag; 

public: 
    __property   String Name={read=FName,write=FName}; 
    __property   String Address={read=FAddress,write=FAddress}; 
    __property   String PhoneNumber={read=FPhoneNumber,write=FPhoneNumber}; 
    __property   String Hints={read=FHints,write=FHints}; 
    __property   int    Tag={read=FTag,write=FTag}; 

}; 



//--------------------------------------------------------------------------- 
// Node의 MetaClass 정보 연결 함수 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::TreeViewCreateGroupNodeClass(TCustomTreeView *Sender, TTreeNodeClass &NodeClass) 
{ 
     NodeClass = __classid(TGroupNode); 
} 
void __fastcall TForm1::TreeViewCreatePersonNodeClass(TCustomTreeView *Sender, TTreeNodeClass &NodeClass) 
{ 
    NodeClass = __classid(TPersonNode); 
} 





//--------------------------------------------------------------------------- 
// TreeView에 Node 추가 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    // 
    TGroupNode *GNode; 
    TPersonNode *PNode; 
    for(int i=0;i<3;i++) 
    { 
        //Group-Node추가  
        TreeView1->OnCreateNodeClass=TreeViewCreateGroupNodeClass; 
        GNode=(TGroupNode *)TreeView1->Items->Add(NULL,"Group"+IntToStr(i)); 
        GNode->GroupName="그룹["+IntToStr(i)+"]"; 
        GNode->Data=(void *)1; 

        //Group-Node의 Child에 Person-Node 추가 
        TreeView1->OnCreateNodeClass=TreeViewCreatePersonNodeClass; 
        for(int i=0;i<10;i++) 
        { 
            PNode=(TPersonNode *)TreeView1->Items->AddChild(GNode,"사람"+IntToStr(i)); 
            PNode->Name="사람"+IntToStr(1); 
            PNode->Address="대한 민국  서울"; 
            PNode->PhoneNumber="010-1234-5678"; 
            PNode->Tag=i+1; 
        } 
    } 
} 
//--------------------------------------------------------------------------- 

//--------------------------------------------------------------------------- 
// GroupNode 정보 활용
//--------------------------------------------------------------------------- 
void __fastcall TForm1::PmGroupNameClick(TObject *Sender) 
{ 
    if(TreeView1->Selected==NULL || TreeView1->Selected->Level!=0)return; 
    TGroupNode *GNode=(TGroupNode *)TreeView1->Selected; 
    ShowMessage(GNode->GroupName ); 
} 


//--------------------------------------------------------------------------- 
// Person-Node의 정보 활용
//--------------------------------------------------------------------------- 
void __fastcall TForm1::PmAddressClick(TObject *Sender) 
{ 
    if(TreeView1->Selected==NULL || TreeView1->Selected->Level<1)return; 
    TPersonNode *PNode=(TPersonNode *)TreeView1->Selected; 
    ShowMessage(PNode->Address); 

} 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::PmPhoneNumberClick(TObject *Sender) 
{ 
    if(TreeView1->Selected==NULL || TreeView1->Selected->Level<1)return; 
    TPersonNode *PNode=(TPersonNode *)TreeView1->Selected; 
    ShowMessage(PNode->PhoneNumber); 
} 
//--------------------------------------------------------------------------- 



원리는

원리는 간단하다.

TTreeView에는 OnCreateNodeClass 라는 이벤트가 있다.
이 이벤트 핸들러에서 원하는 Class-Type을 지정해주면
TreeView1->Items->Add() 할때 지정해준 Node-Class의 객체가 생성되는 것이다.


메신져 같은것 만들거나, 다양한 네트워크 관리 화면을 만들때 위 방식을 이용하면
참 좋을것 같다.

+ -

관련 글 리스트
1091 [Controls] TTreeView의 Node클래스를 TTreeNode가 아닌 다른 class로 바꾸기 장성호 8119 2012/06/14
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.