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
[127] Lines 속성을 추가한 TMyLabel 컴포넌트 만들기
이정구 [appleii] 14557 읽음    2007-05-01 14:24
 여러개의 컴포넌트를 조합하여 새로운 컴포넌트를 만들고 싶을 때가 있습니다. 델파이는 다중상속을 지원하지 않으므로 다른 컴포넌트를 포함하는 것으로 다른 컴포넌트의 기능을 이용할 수 있습니다. 델파이 예제는 많지만 C++ Builder 예제는 찾아보기 어렵더군요. C++Builder 로 제작된 컴포넌트가 거의 없다보니 컴포넌트 만들기가 막막합니다. 그래서 간단한 예제로 Label 에 Lines property 를 추가하여 멀티라인이 입력되는 Label 컴포넌트를 만들어 보겠습니다. 
Borland C++Builder 6.0 을 사용합니다.

그럼 시작합니다.

일단, 컴포넌트 제작을 위한 템플릿이 필요합니다. 컴포넌트를 등록해주는 함수가 있고 기본적인 틀이 나와있는 것입니다. 그 다음에는 만들어진 틀 내부를 채워 나가면 되는 것이죠.

File -> New -> Other... -> Component 를 선택합니다.


New Component 에서 Ancestor type: 을 TLabel 을 선택합니다.

 

 
Class name: 은 새로 제작할 컴포넌트의 이름입니다. TMyLabel 로 수정합니다.
  
Pallette Page: 는 컴포넌트가 설치될 팔레트입니다. Samples 팔레트에 설치하는 것으로 합니다. 나중에 소스를 수정하면 원하는 팔레트를 만들어서 설치할 수 있습니다.
  
Unit file name: 은 저장될 디렉토리와 이름을 지정하는 것입니다.
  
Search path: 는 필요한 컴포넌트가 있는 경로입니다.

컴포넌트를 컴파일하면 bpl 은 Projects\bpl 에 저장되고 lib 는 Projects\lib 에 저장됩니다.
  
OK 버튼을 누릅니다.
  
이제 MyLabel.cpp 와 MyLabel.h 가 생겼습니다.
  
MyLabel.cpp 편집화면이 나옵니다. 헤더파일을 편집하기 위해서 에디터 아래의 MyLabel.h 탭을 선택합니다.
  
class PACKAGE TMyLabel : public TLabel
 {
 private:
 protected:
 public:
         __fastcall TMyLabel(TComponent* Owner);
 __publshed:
 };

현재 나와있는 것이라고는 객체 생성시 초기화를 담당하는 생성자만 있으므로 나머지를 채워넣어야 합니다.

필요한 것은 4개 입니다.
(1) 객체가 삭제될 때 , 생성자에서 만든 객체를 파괴할 파괴자. ( public )
(2) 멀티라인 입력속성을 결정하는 Lines property ( __published )
(3) Lines property 의 read 방법 ( private )
(4) Lines property 의 write 방법 ( private )

(1)파괴자는 외부에서 호출해야 하므로 public 영역에 넣습니다.
(2)TMyLabel 에 추가할 Lines 속성은 Object Inspector 에 나타나야 하므로 __published: 섹션에 넣습니다.
(3), (4) Lines 의 read , write 는 외부에서 직접 접근하는 것을 막아야 하므로 private 에 넣습니다.
class PACKAGE TMyLabel : public TLabel
 {
 private:
   TStringList* FLines;  //입력할 내용을 담은 객체의 포인터
   void __fastcall SetLines(TStringList* Lines);  //Lines 의 write 방법
 protected:
 public:
         __fastcall TMyLabel(TComponent* Owner); //생성자
         virtual __fastcall ~TMyLabel();  //파괴자
 __published:
   __property TStringList* Lines = { read = FLines, write = SetLines };  //접근 방법을 지정하는 property
 };

-여기서 잠깐!-

  VCL 컴포넌트는 고유의 명명법이 있습니다. TForm 에서 T는 Type 을 나타내는 것입니다. class 도 Type 이라는 말이
있지요. MFC 에서는 Class 라는 뜻으로 C 를 접두어로 사용하지만 VCL 은 T를 사용합니다. 마찬가지로 class 내부
변수는 Field 를 뜻하는 F를 접두어로 사용합니다. property read 를 위한 함수는 Get 으로 시작합니다. write 를 위한
함수는 Set 으로 시작합니다. 즉, 기본구조는 다음과 같습니다.
class PACKAGE TDerived : public TBase
 {
 private:
   int FValue;                                       //값을 저장할 변수
   int __fastcall GetValue();                   //read 방법
   void __fastcall SetValue(int AValue);  //write 방법

 protected:

 public:
   __fastcall TDerived(TComponent* Owner);
   virtual __fastcall ~TDerived();

 __published:
   __property int Value = { read = GetValue, write = SetValue };
 };


기본적인 아이디어는 TMyLabel 의 객체가 생성될 때 멀티라인의 데이터를 저장할 FLines 객체를 생성하고 TMyLabel 객체가 파괴 될때 FLines 도 같이 파괴하는 것입니다. 객체가 객체를 포함하는 것입니다.

TStringList 등의 T로 시작하는 객체는 new 연산자를 통해서 heap 에서만 생성할 수 있습니다.
생성자에서 new 를 통해서 생성하고 , 파괴자에서 delete 로 파괴한다는 밑그림이 그려집니다.

어떤 객체들은 고유의 property editor 가 있습니다. TPicture 는 그림을 불러오는 Picture Editor 가 있습니다.


TStringList 는 String List Editor 가 있습니다.



property type 으로 TStringList 를 지정하면 String List Editor 를 이용하여 객체에 멀티라인 데이터를 입력할 수 있는 것입니다.


이제 구체적인 구현으로 들어갑니다. MyLabel.cpp 를 선택하여 입력합니다.
__fastcall TMyLabel::TMyLabel(TComponent* Owner)
         : TLabel(Owner)
 {
   FLines = new TStringList(); //객체를 생성
 }

 __fastcall TMyLabel::~TMyLabel()
 {
   delete FLines; //만들었던 객체를 파괴
 }

 void __fastcall TMyLabel::SetLines(TStringList* Lines)
 {
   FLines->Assign(Lines); //String List Editor 에서 입력받은 내용을 FLines 에 저장
   this->Caption = FLines->Text;  //TMyLabel 의 Caption 에 FLines 에 저장된 내용을 표시
 }


자, 이제 컴포넌트를 컴포넌트 팔레트에 등록시키기 위해서 패키지 파일을 만들어야 합니다.
패키지 파일에는 컴파일에 필요한 설정이 들어가 있습니다.

-잠깐!-

  작업을 새로 시작하기 전에 Close All 을 선택하여 모두 닫는 것이 좋습니다. 다른 폼이 열려있는 상태에서 엉뚱하게
저장되었다거나 저장한 줄 알았더니 저장이 안되는 경우가 생깁니다. 확실하게 하기 위해서 새로 시작하기 전에
Close All 을 해줍니다.


File -> New -> Other... -> Package 를 선택합니다.



기본이름이 Package1.bpk 입니다. 저장하기를 눌러서 다른 이름으로 저장합니다.

파일이름을 MyLabel_bcb6.bpk 로 저장합니다. 그러면 자동으로 res , cpp 파일이 추가됩니다.
res 파일은 리소스 파일로 아이콘이나 여러가지 이미지를 넣을 수 있습니다.
cpp파일은 엔트리입니다. 일종의 main 함수입니다.

-또 잠깐!-

  MyLabel.bpk 로 하면 절대 안됩니다! bpk 파일을 만들면 cpp , res 가 같이 생깁니다. MyLabel.bpk 로 저장하면
자동으로 MyLabel.cpp 를 만들기 때문에 앞에서 만들었던 파일을 덮어쓰기 합니다. 때문에 컴포넌트의
엔트리라는 것을 명확히 하기 위해서 식별하기 쉬운 이름을 정해줍니다. C++Builder 6 용이면 _bcb6 정도의 접미사
정도가 적당할 것 같습니다.


이제 , Add 버튼을 눌러서 앞에서 만들었던 MyLabel.cpp 를 추가해야 합니다. 그럼 총 3개의 파일이 포함되는 것을
알 수 있습니다.

MyLabel.cpp
MyLabel_bcb6.cpp
MyLabel_bcb6.res



Options -> Directories/Conditionals 를 선택합니다.

Include Path 에 MyLabel.h 가 있는 곳을 추가합니다.

저장한후 Install 합니다.

아래와 같은 화면이 나와야 합니다. Registered 되었다는 메시지가 나와야 컴포넌트 팔레트에 나타납니다.



File -> New -> Application 해서 새로 만든 컴포넌트 테스트를 해봅니다.
Samples 탭에 TMyLabel 컴포넌트가 생겼습니다. 폼에 drop 한후 Object Inspector 의 properties 를 보면 TLabel 에는 없던 Lines 속성이 생긴것을 알 수 있습니다. 클릭하면 String List Editor 가 나타납니다. 여러줄을 입력해 봅니다.
다음과 같이 멀티라인이 입력되는 Label 이 생겼습니다.




예제로 만든 MyLabel 컴포넌트를 첨부합니다.

김태선 [cppbuilder]   2007-05-01 14:58 X
아주 좋은 강좌군요. 멋집니다. ^^;

Skyz [park317]   2007-05-01 21:58 X
흠 빌더 컴포넌트 제작에 많은 도움이 될듯합니다.
노고에 감사드립니다.^^
장성호 [nasilso]   2007-05-03 00:19 X
그림으로 이해하기 쉽게 해놓은  좋은강좌네요
예전에 컴포넌트 처음만들때 삽질했던 기억이.... 새록 새록 나네요

감사합니다.
이정구 [appleii]   2007-05-03 11:56 X
혹시라도 잘못된 내용이 있으면 댓글 달아주세요. 여기저기 기웃거리면서 눈치로 배운거라서 정확하지 않을수도 있습니다.

+ -

관련 글 리스트
127 Lines 속성을 추가한 TMyLabel 컴포넌트 만들기 이정구 14557 2007/05/01
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.