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
[723] [VCL] VCL 클래스 private 멤버 접근 방법들 소개
장성호 [nasilso] 9180 읽음    2007-12-11 12:52
VCL의 pravate, protected 멤버 접근하기

프로그램을 하다가 보면 종종 pravate 또는 protected멤버에 접근하고 싶을때가 있다.
private멤버에 접근하므로 빙~~ 돌아가야 할 코딩이 간단히 해결되는 경우가 있기 때문이다.
잘쓰면 유용하지만 잘못쓰면 위험할수도 있죠


델마당에 양병규님이 올린 자료와 댓글,
그리고 이곳 볼포 tip게시판의 김태선님과 박지훈님의 글들을 모아서 정리해본다.


방법1. 해당 Class를 상속받아 public으로 재 선언한다.
      김태선님이 소개해준 방법으로 아래 링크에
      TPanel의 protected 멤버인 Canvas를 public으로 쓰는 방법이 소개되어있다.
        http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=546
    class TCanvasPanel : public TPanel 
    { 
    public: 
        __property Canvas; 
    }; 

            

방법2. C++Builder사용자에게만 해당하는것으로 *.hpp파일을 열어서 해당 멤버를 public으로 재선언 해버린다.

      이 방법은 박지훈.임프님께서 소재해준 방법입니다.
      확실하고 편리하지만 위험할수도 있다.
      http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=21


방법3. 델마당 양병규님이 소개해준 방법으로
       class 의 특정 public멤버로 부터 접근하고자 한는 private의 멤버의 offset 값을 계산해서
       포인터연산을 통해 접근하는 방식.

       Screen의  FForms에 접근하여 특정 폼을 list에서 빼버리는 팁
       http://www.delmadang.com/community/bbs_view.asp?bbsNo=3&bbsCat=0&st=&keyword=&indx=398161&keyword1=&keyword2=

    procedure RemoveFromScreen(Form: TForm);
    var
      P: Pointer;
    begin

      P := @Screen.Cursor;

      Inc( PChar(P), SizeOf( Pointer ) * 2 );
      TList( P^ ).Remove( Form );

      Inc( PChar(P), SizeOf( Pointer ) * 1 );
      TList( P^ ).Remove( Form );
    end;

 
       근데 위 내용중 Screen.Cursor의 주소에 접근하는 과정에서
        C++Builder에서는 에러가 난다.
       int * pCur=(int *)&Screen->Cursor;  //이와같이 할경우...
       TCursor *pCur2=(TCursor *)&Screen->Cursor; //또는... 
       에러메세지 : E2027 Must take address of a memory location
     
      C++Builder 에서 
      &Screen->Cursor  가져오는데 error가 난다면  Screen 객체 처음부터 offfset을 계산해서 할수 있다.
    void __fastcall TForm1::Button4Click(TObject *Sender)
    {
        int *iScr=(int *)Screen;
        TList* FForms=(TList *)(*(iScr+19));   
        for(int i=0;iCount;i++)
        {
            ShowMessage(((TForm *)FForms->Items[i])->ClassName());
        }
    }
    //---------------------------------------------------------------------------

      C++Builder 6.0에서는
      Screen과 Screen->FForms의 offset이  0x4C 즉 76Byte 이다. ( 19*4 =76 )    
      C++Builder 2007에서도 괜찮음

      offset을 이용한 방식은 vcl이 아니라도 여러방면에서 매우 유용한다.

방법4.  붕어빵 클래스를 만드는데. 접근을 원하는 멤버르  public으로 해서 ..만들어
       객체를 cast해서 접근하는 방식임
     ( 양병규님글의 댓글에 있었던 내용)
         
     C++Buider로 하면 아래와 같은 방식으로 할수있다.
           
    class TMyScreen : public Classes::TComponent
    {
        typedef Classes::TComponent inherited;

    public:
        Classes::TStrings* FFonts;
        Classes::TStrings* FImes;
        AnsiString FDefaultIme;
        HKL FDefaultKbLayout;
        int FPixelsPerInch;
        Controls::TCursor FCursor;
        int FCursorCount;
        Classes::TList* FForms;
        Classes::TList* FCustomForms;
        Classes::TList* FDataModules;
        Classes::TList* FMonitors;
        TCursorRec *FCursorList;
        HICON FDefaultCursor;
    };
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
        TMyScreen *Scr=(TMyScreen *)Screen;
        for(int i=0;iFForms->Count;i++)
        {
            ShowMessage(((TForm *)Scr->FForms->Items[i])->ClassName());
        }
    }
    //---------------------------------------------------------------------------



헤헤.. 잘 쓰면 유용하고
잘못쓰면... 독이될수도..

그럼..

+ -

관련 글 리스트
723 [VCL] VCL 클래스 private 멤버 접근 방법들 소개 장성호 9180 2007/12/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.