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

C++빌더 Q&A
C++Builder Programming Q&A
[5782] Re:[질문] 동적 팝업메뉴 생성시에... -> dynamic_cast 오류입니다.
박지훈.임프 [cbuilder] 3007 읽음    2001-02-28 10:18
lezo 님이 쓰신 글 :
: 동적으로 PopUp메뉴 생성시에 나는 오류를 바로잡는데 도와주세요. T_T
: 일단 저의 상황을 설명하죠.
: --------------------------
: 1. 폼에 팝업 컴포넌트를 올려놓고 팝업연결속성이 없는 ActiveX객체를 마우스 오른쪽 클릭할때 팝업 메뉴가 생성되게 하는데 목적이 있습니다.
:
: 2. 폼위에는 ActiveX객체 1개, 팝업 컴포 1개, 그외 버튼 몇개.. ..
:
: 3. 헤더파일에 동적으로 팝업 메뉴를 설정하기위해 TMenuItem* 을 하나 선언하고 ActiveX객체의 OnClick이벤트에 마우스 오른쪽 버튼이 발생할 시에 팝업메뉴를 띄우고(폼 초기화시 팝업 메뉴를추가했습니다.)
:
: 4. 팝업 메뉴가 클릭 되었을때 어떤 메뉴가 클릭되었는지 구별하는 것입니다.
: (즉, 팝업 메뉴가 클릭되면 모두 동일한 이벤트가 발생합니다.)
:
: 그 이벤트에서 어떤메뉴가 실행되었는지 구별하려고 이럴때쓰는 dynamic_cast를 사용했는데...
: 액세스 바이얼레이션이.. ㅡ.ㅡ;;
: 그럼 그 이벤트의 소스 부분을 보시고 혹시 짚히시는 부분이 있으면 답해주세요.
: 뭔가 이유는 있는거 같은데.. 머리가 띵~ 해지니 아무런 생각도 없고.. 혹시 해결방법이나 돌아갈
: 방법이 있으면 한마디 적어주세요.
: 아님 그냥 이러면 되지않을까라도.. ㅡ_ㅡ;;
:
:
: ----- 문제의 이벤트... ㅡㅡ; --------
: // PopUpMenu Click Event (User Define)
: void __fastcall TForm1::PMenuItemClick(TObject *Sender)
: {
:     if((dynamic_cast<TPopupMenu *>(Sender))->Items->Caption == "Click1")
:         ShowMessage("팝업메뉴를 클릭하셨습니다1");
: }


임펠리테리입니다.

dynamic_cast는, 캐스팅하려는 타입으로 캐스팅이 불가능한 경우에는 NULL을 리턴합니다. 그런데, lezo님의 코드를 보면, 이벤트 핸들러는 메뉴아이템에 대해 작성되어 있으므로 이 이벤트 핸들러에 넘어오는 Sender는 역시 메뉴아이템 객체가 되지요. 이것을 팝업메뉴 형으로 캐스팅하려고 했으므로 당연히 널이 리턴되게 됩니다. 아마도, 팝업메뉴와 메뉴아이템을 혼동하신 듯 하네요.

다음과 같이 코드를 수정하시면 잘 될겁니다.
void __fastcall TForm1::PMenuItemClick(TObject *Sender)
{
    if((dynamic_cast<TMenuItem *>(Sender))->Caption == "Click1")
        ShowMessage("팝업메뉴를 클릭하셨습니다1");
}

한가지 더. 메뉴아이템의 이벤트핸들러로 넘어오는 Sender는 특별한 일이 없다면 반드시 메뉴아이템 객체겠지요? 여기서 "특별한 일"이라고 말씀드린 경우는, 이 이벤트 핸들러를 버튼의 클릭 이벤트 등과 공유하는 경우를 말하는 것입니다. 이러한 경우에 이벤트가 버튼에서 발생했는지 메뉴 아이템에서 발생했는지를 구별할 수 있는 방법이 dynamic_cast이구요. 만약 이 이벤트 핸들러가 메뉴아이템에만 연결되어 있다면 굳이 속도가 느린 dynamic_cast를 쓰실 필요는 없습니다. 그리고 어차피 사용하신 코딩에서는 캐스팅한 값이 널인지를 검사하고 있지 않으므로 그대로 쓸 수도 없구요.

만약 이 이벤트핸들러가 메뉴아이템에만 연결되어 있다면,
void __fastcall TForm1::PMenuItemClick(TObject *Sender)
{
    if(((TMenuItem *)Sender)->Caption == "Click1")
        ShowMessage("팝업메뉴를 클릭하셨습니다1");
}
이렇게 일반 캐스팅을 하는 것이 속도면에서 유리합니다.

그리고 다른 이벤트 핸들러와 공유하는 경우, 메뉴아이템일 경우에만 따로 처리하고자 한다면,
void __fastcall TForm1::PMenuItemClick(TObject *Sender)
{
    TMenuItem *Item = dynamic_cast<TMenuItem *>(Sender);
    if(Item != NULL)
    {
        if(Item->Caption == "Click1")
            ShowMessage("팝업메뉴를 클릭하셨습니다1");
    }
    else
        ... // 이벤트가 메뉴아이템이 아닌 곳에서 발생한 경우
}
이렇게 검사하면 됩니다.

그럼 참고하시길...

+ -

관련 글 리스트
5780 [질문] 동적 팝업메뉴 생성시에... lezo 2666 2001/02/28
5782     Re:[질문] 동적 팝업메뉴 생성시에... -> dynamic_cast 오류입니다. 박지훈.임프 3007 2001/02/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.