2013-03-11 2 views
1

내가사용자 정의 구성 요소 TImage의 이벤트가 발생 오류가

private 
    { Private declarations } 
    ... 
    fOnImageClick: TNotifyEvent; 
    fOnImageMouseUp: TMouseEvent; 
    fOnImageMouseDown: TMouseEvent; 
    fOnImageMouseMove: TMouseMoveEvent; 
    fOnImageMouseEnter: TNotifyEvent; 
    fOnImageMouseLeave: TNotifyEvent; 
    fOnImageSelect: TNotifyEvent; 
    fOnImageDblClick: TNotifyEvent; 
    protected 
    ... 
    public 
    { Public declarations } 
    ... 
    published 
    ... 
    property OnImageClick: TNotifyEvent read fOnImageClick write fOnImageClick; 
    property OnImageSelect: TNotifyEvent read fOnImageSelect write fOnImageSelect; 
    property OnImageDblClick: TNotifyEvent read fOnImageDblClick write fOnImageDblClick; 
    property OnImageMouseDown: TMouseEvent read fOnImageMouseDown write fOnImageMouseDown; 
    property OnImageMouseUp: TMouseEvent read fOnImageMouseUp write fOnImageMouseUp; 
    property OnImageMouseMove: TMouseMoveEvent read fOnImageMouseMove write fOnImageMouseMove; 
    property OnImageMouseLeave: TNotifyEvent read fOnImageMouseLeave write fOnImageMouseLeave; 
    property OnImageMouseEnter: TNotifyEvent read fOnImageMouseEnter write fOnImageMouseEnter; 
    end; 

내가 부모가 TPanel과 whos는 부모

img:= TImage.Create(ThumbPnl); 
img.Parent:= ThumbPnl; 
img.Tag:= I; 
img.Align:= alClient; 
img.Stretch:= true; 
img.OnClick:= fOnImageClick; 
img.OnDblClick:= fOnImageDblClick; 
img.OnMouseEnter:= fOnImageMouseEnter; 
img.OnMouseLeave:= fOnImageMouseLeave; 
img.OnMouseDown:= fOnImageMouseDown; 
img.OnMouseUp:= fOnImageMouseUp; 
img.OnMouseMove:= fOnImageMouseMove; 
TScrollBox

인 TImage의에 할당 다음 이벤트 기호와 사용자 정의 구성 요소가 "존재하지 않는다"

구성 요소가 컴파일되고 올바르게 bulds됩니다. 이 구성 요소가있는 응용 프로그램은 jus를 컴파일하여 실행합니다. OnClick 이벤트를 할당하면 작동합니다. 다른 모든 이벤트는 앱을 할당하고 앱을 실행하려고하면 이벤트가 존재하지 않는다고 말하는 오류가 발생합니다.

왜 그런지 알 것입니다.

+3

정확한 오류 메시지를 알려주십시오. 오류 메시지를 설명하지 마십시오. 따옴표. 그대로. –

답변

2

이벤트 란 무엇입니까

델파이의 이벤트는 메소드 포인터입니다. 메소드 포인터는 기본적으로 두 개의 포인터입니다. 한 포인터는 이벤트에 지정한 메소드를 나타내고, 다른 포인터는 지정한 라이브 인스턴스 (오브젝트)를 나타냅니다.

난 당신이

를 기대한다고 가정 내가 당신이 당신의 내면의 객체에서 이벤트가 외부 객체에 할당 된 이벤트를 다음과 기대 생각, 그것은 자동으로 수행되지 않습니다.

할당하면 포인터 할당이 수행됩니다. 그래서

img.OnDblClick:= fOnImageDblClick; 

fOnImageDblClick이 시간에이 값으로 포인터 할당을 수행하여 라인, 예를 촬영합니다. nil 인 경우 img.OnDblClick은 지금부터 nil이됩니다. 그것은 점은 당시 Form1.MyComponentImageClickimg.OnDblClick 지금부터 동일한 개체에 같은 방법을 가리 킵니다 경우, 하지만, 당신은 나중에 어디 fOnImageDblClick 포인트를 변경하면 imgOnDblClick는 ... 그것은 남아 가리키는 것이다 따르지 않습니다 같은 오래된 주소. 코드를 변경하려면 코드별로 변경해야합니다.

원할 경우 외부 클래스의 이벤트 설정자에서 수행 할 수 있습니다.

첫째,이 같은 이벤트를 선언하여 Img 내부 객체가 항상 존재하는 경우

published 
    ... 
    property OnImageDblClick: TNotifyEvent read fOnImageDblClick write SetOnImageDblClick; 

... 
procedure TMyClass.SetOnImageDblClick(Value: TNotifyEvent); 
begin 
    FOnImageDblClick := Value; 
    //pass the new value to the inner object. 
    if Assigned(Img) then 
    Img.OnDblClick := Value; 
end; 

, 당신은 FOnImageDblClick 변수를 필요가 없습니다, 당신은 또한 속성에 대한 게터를 작성하고 걸릴 수 있습니다 값은 다음과 같이 내부 객체에서 직접 가져옵니다.

function TMyClass.GetOnImageDblClick: TNotifyEvent; 
begin 
    Result := Img.OnDblClick; 
end; 
+0

불행히도, img가 생성되고 모든 이벤트가 할당 된 스 니펫 코드는 구성 요소의 보호 된 메서드 (UpdateViewer)에서 루프에 있습니다. n 개의 번호가있을 수 있습니다. 이미지 뷰어 구성 요소입니다. 따라서 setter 메서드에서 액세스 할 수 없습니다. 다른 방법이 있습니까? – JakeSays

+0

img 변수를 로컬에서 로컬 위치로 이동하여 구성 요소의 전역 위치 (개인 섹션)로 - 지금 훌륭하게 작동합니다! – JakeSays

6

새로운 구성 요소 작성자는 매우 일반적인 실수를 저지르고 있습니다. 당신은이 규칙을 깨고있다 :

구성 요소 사용자가 이벤트 핸들러를 쓰기를, 구성 요소 작가 "화재"이벤트 당신이 구성 요소 개발자가 안으로 할 때 이벤트를 할당한다 무엇을하고 있는지 귀하의 경우에는

그렇게 해. OnClick, OnDblClick 등 이벤트에서 코드를 할당하는 것은 구성 요소 사용자의 몫입니다.

Published 및 TNotifyEvent 형식으로 이벤트를 선언하면 충분합니다.

property OnSomeEvent: TNotifyEvent read FOnSomeEvent write FOnSomeEvent; 

이벤트를 작성하기 만하면됩니다. 당신의 일은 그들을 "해고"하는 것입니다. 즉, 그들이 일어나게하십시오.

적절한 시점에 구성 요소에서 수행됩니다. 일반적으로, DoXXXX 메소드를 생성합니다. 여기서 XXXXX는 발생하는 것입니다. 이벤트가 해고되어야한다 그래서 당신은 당신은 단순히 DoSomeEvent 전화, 코드 내에서, 그리고

procedure TMyImage.DoSomeEvent; 
begin 
    if Assigned(FOnSomeEvent) then FOnSomeEvent(Self); 
end; 

을 만들 것입니다.

이제 의 기본 이벤트 기능을 향상 시키려면 이벤트를 발생시키는 메서드를 재정의해야합니다.

나는 그것을 싫어,하지만 내 고전적인 구성 요소 TSmiley은 간단하고 명확하게 보여

http://tsmiley.svn.sourceforge.net/viewvc/tsmiley/

는 예를 살펴과 이벤트를 만드는 방법을 볼 수 있습니다.

+0

+1 "나는 그것을 할 수 없어"와 고전 TSmiley 구성 요소. : p – jachguate

+0

질문은 다른 시나리오를 설명합니다. 질문에있는 코드는 이미지 이벤트가 발생하면 사용자 이벤트가 실행되기를 원합니다. 따라서 이미지 이벤트는 구성 요소에 정의 된 핸들러로 설정해야합니다. 그리고 그들은 차례대로 '배정 된 (FOnSomeEvent), FOnSomeEvent (Sender),'춤을합니다. –