C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[3281] Re:Re:패패루님 도와 주세요~
만해 [greenuri] 2788 읽음    2002-01-23 09:55
패패루 님이 쓰신 글 :
: 질문을 미처 못 봤던 것 같군요.. ^^ 죄송함다..
: 답변을 어디다 적을까 한참 망설이다가.. 질문이 너무 뒤로 가버려서 그냥 여기다
: 적겠습니다.. (아.. 남들눈을 의식하는 패패루.. 케케케)
:
: 음.. 일단, VirtualTree는 패러다임 자체가 기존의 트리뷰와는 많이 다릅니다.
: 그래서 만해 님이 혼돈하시는 부분이 있는 것 같군요.
:
: 어떻게 설명드려야 좋을지 저도 좀 고민하게 되는데... 음....
: 으그.. 한참 써 내려가다가 몽땅 지웠슴다.. ㅠ ㅠ 일반적인 사용법은 따로 다루도록
: 하고, 님이 질문하신 내용에 한정지어서 답변 드리겠습니다.
:
: 님이 적으신 코드는 메모리 누수까지 동반하고 문제가 좀 심각해 보입니다.
: TVirtualTree는 노드가 생성될 때 각 노드마다 NodeDataSize에 지정된 만큼의 크기로
: 메모리를 할당합니다.
: 따라서 님이 적으신 코드는 노드가 하나 생성될 때 마다 TTreeData의 크기인 12byte씩
: 메모리를 할당을 하게 되는데 엉뚱하게도 여기에 TTreeData* 타입(4byte)의 데이터를
: 대입하는 아주 이상한 구조입니다.
:
: 다음과 같이 하셔야겠죠.
: 두가지 접근 방향을 제시하겠습니다.
:
: 1. TTreeData의 생성을 TVirtualTree에 맡기는 방법
:
: void __fastcall TForm1::OnCreate(TObject* Sender)
: {
:   VirtualStringTree2->NodeDataSize = sizeof(TTreeData);  //sizeof를 눈여겨 보세요 12byte
: }
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
:   TVirtualNode* pNode = VirtualStringTree2->AddChild(NULL,NULL); // 루트에 노드 생성
:   // 옛날 버전에서는 AddChild의 파라미터로 UserData는 넘길 수 없었습니다. 하여간..
:   // 다음과 같이 써도 무방...
:   // TVirtualNode* pNode = VirtualStringTree2->AddChild(NULL); //루트에 노드 생성.
:   // 노드가 추가되면서 TTreeData를 담을 수 있는 12byte만큼의 메모리가 할당됩니다.
:   // 따라서 new를 쓸 필요가 없지만 한가지 주의하십시요.
:   // TTreeData를 struct를 안쓰고 class로 구현했을 경우, TTreeData의 컨스트럭터는 동작을
:   // 할까요 안할까요??? ^^ 당연히 동작 안합니다!!! 이런 경우는 다른방법을 써야 합니다.
:   // 그리고 할당된 메모리의 파괴도 역시 TVirtualTree가 담당합니다.
:   // TTreeData의 디스트럭터는 동작할까요?? 당연히 동작 안합니다.
:
:   TTreeData* pData = (TTreeData*)(VirtualStringTree2->GetNodeData(pNode));
:   pData->Data = "Test";
:   pData->ID = 1;
:   pData->Depth = 1;
: }
:
: 이렇게 채우는 겁니다. new로 TTreeData를 생성하는 부분이 전혀 없지만 정상 동작합니다.
: 아니면 다음과 같이 합니다.
:
:
: 2. 사용자가 직접 메모리 관리하기.. 포인터만 저장
:
: void __fastcall TForm1::OnCreate(TObject* Sender)
: {
:   VirtualStringTree2->NodeDataSize = sizeof(TTreeData*);  //sizeof를 눈여겨 보세요 4byte
: }
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
:   TTreeData* pData = new TTreeData();
:   pData->Data = "Test";
:   pData->ID = 1;
:   pData->Depth = 1;
:
:   TVirtualNode* pNode = VirtualStringTree2->AddChild(NULL,pData); // 루트에 노드 생성
: }
:
: 메모리 누수를 막기 위해 당연히 OnFreeNode에
:   TTreeData* pData = *((TTreeData**)(VirtualStringTree2->GetNodeData(Node)));
:   delete pData;
: 와 같은 코딩이 필요하겠죠. 포인터의 포인터를 쓴 것을 눈여겨 보셔야 할겁니다.
:
: 어쨌건, 데이터를 이렇게 넣었다고 화면에 뭔가 나올걸 기대하시면 안됩니다.
: 어찌보믄 엄청 불합리해 보이지만 이 성질을 잘 이용하면 정말 눈알튀어나오는걸 만들 수
: 있습니다.
:
: 화면에 뭔가 뿌려주려면 다음과 같이 하시면 됩니다.
:
: OnGetText 이벤트에 코딩합니다.
: void __fastcall TForm1::vstTestGetText(TBaseVirtualTree *Sender,
:       PVirtualNode Node, int Column, TVSTTextType TextType,
:       WideString &CellText)
: {
: // 첫번째 경우를 쓴 겁니다.
:   TTreeData* pData = (TTreeData*)(VirtualStringTree2->GetNodeData(pNode));
:   switch (Column)
:   {
:     case 0: // 첫번째 칼럼인 경우
:       CellText = pData->Data;
:       break;
:     case 1: // 두번째 칼럼인 경우
:       CellText = "아뒤"+IntToStr(pData->ID);
:       break;
:     case 1: // 세번째 칼럼인 경우
:       CellText = "기피"+IntToStrDef(pData->Depth, 0);
:       break;
:   }
: }
: 이젠 화면에 뭔가 나오는 것을 볼 수 있을겁니다.
: TTreeView와 간단히 비교해 보면,
: 루트노드에 100만개를 표시할 때를 생각해 보죠.
: TTreeView에서는 100만번 루프를 돌리면서 TTreeView->Items->AddChild()함수를
: 100만번 호출, 각각의 100만개의 캡션에 뭔가 값을 넣어줘야 합니다.
: TTreeView를 단순히 내가 따로 관리하는 데이터를 표시해 주는데만 쓴다면, 어마
: 어마한 메모리 낭비에 엄청난 시간이 필요하겠죠.
: 하지만 TVirtualTree에서는 화면 표시에 필요한 만큼만 OnGetText이벤트가 호출
: 됩니다. 화면 표시를 위해 캡션데이터를 복사할 필요도 없고, 자신이 갖춰놓은
: 자료구조에 TVirtualTree가 달라붙는 형식으로 동작시킬 수 있죠.
: 100만개 추가해도 화면에 달랑 10개만 보인다면 10개 데이터 접근 속도밖에 안걸
: 리는 겁니다.
: 아.. 졸려.. 나중에 안졸릴때.. 이런건 아예 강의가 필요할 것 같은데...
: 하여간.. 필요하다면 나중에 좀 더 자세히 알려드리겠습니다.
: 여기 계신 많은 고수님들을 마구 괴롭히세요.. 애꿎은 저는 좀 봐주시구요. 헤헤
:
: PS. 만해님은 Virtual Tree 설치 제대로 되시던가요??
: 전 dsgnintf는 라이브러리 패스에 source\ToolsAPI를 첨가해서 되는데 그담에
: colnedit는 죽어라구 안됩니다.. 아무래도 정답은 dsnide50.lib가 있어야 하는
: 분위긴데.. 어흑... 디자인 타임 패키지니까 좀 빠져도 상관 없긴 하지만 그래두
: 기분 꿀꿀... 그쪽 뉴스그룹에도 동일한 문제가 올라왔는데 다들 답은 안주구
: 엉뚱한 얘기들만 하고 있더군요.. 우이쓍~~~
:
:
: 만해 님이 쓰신 글 : 카피한겁니다.
: 안녕하세요 만해입니다.
:
: 어제 컴포넌트 자료실에 있는 VirtualTree 컴포넌트를 다운 받아서
:
: 천신만고 끝에 깔아서
:
: 지금 사용하고 있는데요
:
: 그냥 단순히 자료 넣는건 알겠는데
:
: 제가 원하는 형식으로 자료를 넣을려니깐
:
: 잘 안되네요
:
: 지금 도움말도 뒤지고 했는데도 잘 모르곘고
:
: 도움 부탁 드립니다.
:
: typedef struct
: {
:   AnsiString Data;
:   LONG ID;
:   LONG Depth;
: }TTreeData;
:
: 이건 헤더 파일에 정의된 데이타 형이고요
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
: TTreeData* Data = new TTreeData;
: Data->Data = "Test";
: Data->ID = 1;
: Data->Depth = 1;
: VirtualStringTree2->NodeDataSize = sizeof(Data);
: VirtualStringTree2->AddChild(NULL,(void*)Data);
: }
:
: 이건 자료를 입력 하는 루틴입니다.
:
: 분명히 도움말에 나온것 처럼 구조제를 만들어서 집어 넣는데도
:
: 제가 원하는 식으로는 안나오고
:
: 그냥 기본형만 나오네요
:
: 고수님들의 도움 부탁 드립니다.
:

안녕하세요 만해 입니다.

저는 그거를 패패루님이 올리전에 웹에서 다운 받았었거든요

저도 엄청 해매다가

패패루님께서 올린 글을 보면서 했고요

dclstd50.lib는 제가 일부러 dclstd50.bpi 파일을 패키지에 추가 시켜서

해결 했네요

그 외에는 저도 좀 많이 해맷네요

우선 패패루님의 답변을 기초로 한번 해 보고 안되면 패패루님을 비롯한 다른 고수님들께 질문을~

참 저 25일날 올라 갑니다~

많은 분들 참석해 주세요~

임프님은 예전에 천리안에서 모임할때 뵜었는데

다른분들은 처음 뵙는 분들이라서

많은 분들을 뵙으면 하네요

그럼 이만



+ -

관련 글 리스트
3264 임프님이 요청하신 테스트 결과입니다.(오타정정 빌더6->빌더5) 패패루 2765 2002/01/21
3271     패패루님 도와 주세요~ 만해 2616 2002/01/22
3276         Re:패패루님 도와 주세요~ 패패루 2612 2002/01/22
3281             Re:Re:패패루님 도와 주세요~ 만해 2788 2002/01/23
3265     Re:임프님이 요청하신 테스트 결과입니다. 박지훈.임프 2563 2002/01/22
3273         ^^ 초청해 주셔서 고맙슴다~~ 꾸벅(냉무) 패패루 2491 2002/01/22
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.