먼저.. 질문은 Q/A 게시판에! ^^
Samples 탭의 컴포넌트들은 말 그대로 샘플일 뿐, 실제로 사용하기에는 기능이 미약하거나 버그가 있는
컴포넌트가 대부분입니다. 그래서 샘플 탭에 있지요. 전 샘플 탭에 있는 컴포넌트들은 절대로 쓰지 않습니다.
방금 TTrayIcon 컴포넌트의 소스를 보니 말씀하신 것과 같은 문제를 일으킬 명백한 버그가 있네요.
아니 버그라기 보다는, 구현을 '덜' 한 거라고 보는 게 더 정확하겠습니다만.
Icons 속성에 대해 Set, Get 함수를 구현하지 않고 직접 FIconList라는 내부 필드에 연결한 탓이죠.
다른 컴포넌트를 가리키는 속성을 구현할 경우, Get 함수는 필요하지 않지만 Set 함수는 반드시 필요합니다.
단순히 함수를 구현하는 것이 필요한 것이 아니라, Set 함수 안에서 처리해야 할 절차가 있기 때문입니다.
더 자세히 설명하자면 컴포넌트 개발 강좌가 되어버리니 생략하고, 결론만 말하자면 Set 함수 내에서
뭔가를 체크해서 FreeNotification() 함수와 RemoveFreeNotification() 함수를 호출해야 하는데 그 절차가
통째로 다 빠져버리고 바로 내부 필드에 연결된 탓입니다.
이 버그 때문에 정확히 말씀하신 것과 같은 런타임 액세스 바이올레이션 예외가 발생합니다.
Icons 속성이 가리키는 컴포넌트가 파괴된 경우에 그 사실을 알지 못하고 멤버에 접근하려고 시도하게 되죠.
비단 서로 다른 폼에 있어서 발생하는 것이 아니라, 같은 폼에 있어도 에러가 날 수 있습니다.
(같은 폼에 있으면 아마 경우에 따라 에러가 안나는 경우도 있고 나는 경우도 있을 겁니다)
앞에서도 말했지만, Samples 탭의 컴포넌트는 말 그대로 샘플일 뿐 실제로 사용하기에는 문제가 많습니다.
예를 들면 SpinEdit 같은 경우에도 문제가 많죠. (빌더 3, 4 버전때 본 버그들인데 아마 지금도 있겠죠)
꼴.시크릿 님이 쓰신 글 :
:
: 콤포넌트를 만들다가 문제가 있어서
: 빌더 버그인지 확인하려고 합니다.
: 간단한 것이니 한번씩 해보고 결과 좀 알려주세요
:
: 일단 새 프로젝트를 만듭니다.
: 그리고 새 폼을 하나 더 만듭니다. 즉 Form1과 Form2가 만들어집니다.
:
: Form1에 빌더의 Sample탭의 TTrayIcon을 올려놓습니다.
: Form2에는 Win32탭의 TImageList 하나를 올려놓습니다.
: 그림과 같이 Unit1에 Unit2의 헤더를 포함시킵니다.
: 그림과 같이 TrayIcon1의 Icons프로퍼티에 Form2->ImageList1을 연결합니다.
:
: 그리고 Form2에 가서 ImageList1을 삭제하고
: 다시 Form1의 TrayIcon1을 클릭해 봅니다.
:
: 테스트 하려는것은 다른 폼에 연결된 콤포넌트의 삭제 여부를 제대로 처리해 주는가 하는겁니다.
:
: 제가 만든 콤포넌트나 TTrayIcon 의 경우 아래 그림과 같은 에러가 발생하면서 빌더가 먹통이 되어 버렸습니다.
: 하지만 vcl 기본 콤포넌트들 예를 들어 TComboBoxEx 같은 것들은 전혀 문제없이 삭제가 됩니다.
:
: 이 차이가 무엇일까요? 질문하고는 좀 다른것 같아서 자유게시판에 올립니다.
:
: 빌더 Update를 설치하면 해결되는것인지 모르겠습니다.
:
: 테스트 후 자신의 빌더 Update 버전과 함께 결과 또는 해결책을 아시면 알려주시길...
:
:
|
근데.. 같은 폼일 경우에는 에러가 안뜰것 같군요. 아래 도움말 보면 Owner가 같은경우 자동으로 Notification이 호출 된다고 합니다. 암튼 골칫거리가 해결됐습니다. 감사~~
void __fastcall FreeNotification(TComponent* AComponent);
Description
Use FreeNotification to register AComponent as a component that should be notified when the component is about to be destroyed. It is only necessary to register components this way when they are in a different form or have a different owner. For example, if AComponent is in another form and uses the component to implement a property, it must call FreeNotification so that its Notification method is called when the component is destroyed.
For components with the same owner, the Notification method is called automatically when an application explicitly frees the component (for example, using the delete keyword). This notification is not sent out when components are freed implicitly (because the Owner is freed).