|
: 새해 복 많이 받으세요!!!
:
: 예를 들어, 한 화면에 A,B,C라는 이름을 가진 각각의 버튼이 있다고 하면, 제가 하고 싶은 일은
: 세 버튼 중 한 버튼을 누른 경우 눌러진 버튼의 이름이 보여지도록 하고 싶거든요....
: 어느 버튼을 눌렀느냐에 따라 해당 프로세스를 다르게 하려구요...
:
: void __fastcall TForm1::ButtonAClick(TPersistent *Sender)
: {
: AnsiString temp;
:
: temp = Sender->GetNamePath();
: ShowMessage(temp);
: }
: 이렇게 하기는 했는데 TObject를 TPersistent로 바꿔서인지 시스템이 굉장히 불안해진 것 같아서
: 다른 더 좋은 방법을 찾고 있지요.
:
: 부디 알고계시다면, 꼭 알려주세요.
임펠리테리입니다.
이벤트핸들러의 인자의 형을 임의로 바꾸어서는 안됩니다. 만약 넘겨받은 Sender를, 상속단계중
하위 클래스형으로 받아야 할 경우라면 캐스팅을 하면 됩니다. C/C++ 표준 캐스팅을 쓸 수도 있고,
빌더에서 새로 도입된 dynamic_cast를 쓸 수도 있습니다. 표준 캐스팅이 무조건 해당 형으로
변환된 포인터를 리턴하는 데 비해, 다이나믹캐스팅은 변환하려고 하는 원본 포인터가 캐스팅되는
것이 잘못일 경우에는 NULL을 넘겨줍니다.
TPersistent::GetNamePath() 함수는 내부적인 용도로만 쓰는 것이 좋습니다. 빌더의 헬프에도
그렇게 나와 있구요. 이 함수는 VCL의 내부에서 사용되고, 새로운 컴퍼넌트를 만드는 경우에도
사용할 수 있지만, 일반적인 프로그램에서 쓰는 것은 좋지 않습니다.
컴퍼넌트의 이름을 알아내기 위해서는 TComponent::Name 프로퍼티가 있지요?
결론은, 넘겨받은 TObject *형인 Sender를 TComponent형으로 캐스팅하고, 캐스팅된 포인터로부터
Name 프로퍼티를 읽으면 됩니다. 만약 이름 검사를 할 객체들이 모두 컴퍼넌트라면 TComponent
클래스로부터 상속을 받았으므로 굳이 다이나믹캐스팅을 해서 검사할 필요는 없고 표준 캐스팅을
쓰면 됩니다. (경우에 따라 이벤트를 발생시키는 객체가 컴퍼넌트가 아닐 경우도 있습니다. 이런
경우엔 당연히 TComponent인가를 검사해야 합니다.)
다음과 같이 수정하면 되겠지요?
void __fastcall TForm1::ButtonAClick(TObject *Sender)
{
AnsiString SenderName = ((TComponent *)Sender)->Name;
ShowMessage(SenderName);
}
그럼 참고하시길...
|