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
[588] C++빌더에서도 폼디자인 컴포를 내 컴포로 바꾸는 3번째 방법.
김태선 [jsdkts] 7852 읽음    2006-04-04 18:36
폼 디자인시 기존의 컴포넌트로 화면을 디자인하고
특정 컴포넌트를 내가 만든 컴포넌트로 대치하는 방법에 대해
2번에 걸쳐서 기사를 썼습니다.

첫번째는 namespace를 바꾸는 방법이고,
두번째는 범위지정자를 이용한 트릭이었습니다.
오늘 소개할 세번째 방법은
델마당의 양병규님 기사를 보고 C++에서도 함보자는 생각에
그 내용에 해당하는 VCL 소스 코드를 찾아 검토한 뒤 동일하게 구성될 수 있다는 점을 확인한 후
테스트 코드를 만들어 실험해 보니 잘되고 별다른 문제가 없어
볼프에 팁 기사로 올리게 되었습니다.

아래는 양병규님의 기사입니다.
http://www.delmadang.com/cwb-bin/CrazyWWWBoard.exe?db=dmdres3&mode=read&num=5189&page=2&backdepth=1
그런데 오늘 보니 무슨 문제가 있다고 소개 기사가 적힌 doc 파일을 삭제했군요.
아마 CreateComponent 구현에 문제가 있는 듯 했습니다. C++에서라면 적용 안될 내용인 듯.

하지만 제가 소개하는 내용과 샘플은 별다른 이상이 발견되지 않아 올립니다.
사실 양병규님이 2가지 방법을 제시했는데, 저는 첫번째 방법만 C++ 빌더로 옮겨본 것입니다.
혹 문제가 발견되면 나중에라도 리플을 달아 알려 드리겠습니다.

빌더에서도 디자인한 컴포넌트를 런타임시에 자신이 제작하거나 동일한 프로퍼티를 수용할수 있는 컴포넌트로
대치할 수 있다는 것은 너무나 흥미로운 일입니다.
가령 특정 컴포넌트의 디자인을 실행중에 Skin 처럼 변경가능할 뿐 아니라, 기능 자체도 완전히 다르게
제작할 수 있다는 것을 의미하고, 그외 여러가지 응용을 가능하게 하기 때문입니다.

그러면 소스 나갑니다.
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
unit1.cpp 아무런 수정 내용이 없습니다.

다음은 헤더를 볼까요.

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
// 새로 패널 컴포넌트를 정의해서 만듭니다.
class TMyPanel : public TPanel
{
private:
    TColor    NewColor;
public:
    __fastcall TMyPanel(TComponent *Owner, TColor cl = clRed) : TPanel(Owner)
    {
        Color = cl;  // 패널을 생성하면 기본 바탕이 붉은 색이 되게 합니다. 왜냐구요. 대~한민국~
    }
    void    color()  // 이렇게 유저 함수를 추가하는 것도 아무 문제 없습니다.
    {
        Color = clBlue;
        NewColor = Color;
    }
};
//---------------------------------------------------------------------------


class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TPanel *Panel1;
    TPanel *Panel2;
private:    // User declarations
public:        // User declarations
    __fastcall TForm1(TComponent* Owner);

    //---------------------------------------------------------------------------
    // 실제 폼에 컴포넌트를 DFM 파일에서 읽어 만들때 ReadState 함수를 이용하는데
    // 이를 오버라이드하면서 하나의 컴포넌트당 생성할 기회를
    // 사용자에게 OnCreateComponent 이벤트 핸들러를 통해 위임가능하게 되어 있으므로
    // 이를 이용하기 위해 CreateComponent 핸들러를 지정한다.
    virtual void __fastcall ReadState(TReader *Reader)
    {
        Reader->OnCreateComponent = CreateComponent;
        inherited::ReadState(Reader);
    }
    void __fastcall CreateComponent(TReader* Reader, TMetaClass* ComponentClass, TComponent* &Component)
    {
        // 원하는 컴포넌트를 다른 것으로 대신 대치하여 생성할 수 있다.
        // 바꾸지 않으면 Component 가 NULL 상태 그대로 호출함수인 ReadState로 돌아가고, 그기서 원래의 컴포넌트로 생성된다.
        if (ComponentClass == __classid(TPanel))
        {
            Component = (TComponent *)new TMyPanel(this);
            // 생성하고 나면 이후 프로퍼티를 DFM에서 읽어 자동으로 세팅한다.
            // 그러므로 대치하는 컴포넌트는 같은 계열이어야 한다.
        }
    }
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

헤더에 설명을 달아 놨습니다.
그냥 구현을 헤더에 바로 해 버렸습니다.
cpp 에 구현부를 두셔도 좋고 이렇게 헤더에 몰아서 코딩하는 것도 좋습니다.
요즘 컴파일러가 좋아 코드가 길지 않으면 별 차이가 없어서리.....

실행하면 화면에 붉은색 패널 2개가 나타납니다.


그럼...

+ -

관련 글 리스트
588 C++빌더에서도 폼디자인 컴포를 내 컴포로 바꾸는 3번째 방법. 김태선 7852 2006/04/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.