|
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
... // 이벤트가 메뉴아이템이 아닌 곳에서 발생한 경우
}
이렇게 검사하면 됩니다.
그럼 참고하시길...
|