2011-01-29 4 views
1

나는 너무 피곤하다고 생각하며 왜 작은 콜백이 작동하지 않는지 이해할 수 없습니다. 동적으로 생성 된 두 개의 프레임이 있는데 첫 번째 프레임을 보여 주며 한 번 클릭하면 두 번째 프레임을 보여줍니다. 두 번째 작업을 마치면 첫 번째 프레임을 표시하고 두 번째 프레임을 비우고 싶습니다. 코드 울부 짖는 소리입니다 : 두 번째 프레임델파이 - 콜백 잘못된 코드

procedure CommingBackFromFrame(aFrame:TFrame); 

procedure TfraMain.ComingBackFromFrame(aFrame:TFrame); 
begin 
if Assigned(aFrame) then 
begin 
try 
    aFrame.Hide; 
    FreeAndNil(aFrame); 
    except on e:Exception do 
//make a log 
    end; 
Self.Show;//first frame show 
end; 



//code which creates the second frame 
    wFrm := TFrameType.Create(Application);//create the second frame 
     with wFrm do 
     begin 
     GoBack:=ComingBackFromFrame(wFrm);//error here 
     parent:=Self; 
     Show; 
     end; //with 
     Application.ProcessMessages; 

코드 : 첫 번째 프레임에 대한

코드

TCallBack = procedure(aFrame:TFrame) of object;//callback declaration 
    TFrameType = class(Tframe) 
... 
    private 
    FGoBack:TCallBack; 
    public 
    property GoBack:TCallBack read FGoBack write FGoBack;//publish callback 
.... 
//at a moment, return to frame 1 

if Assigned(fgoback) then 
GoBack(Self); 

사람이 나에게이 간단한 일을 도와 드릴까요?

+1

이벤트 메서드의 매개 변수를 확보하기 위해 현명한 일이 결코 없다; 기본 객체는 여전히 호출 스택의 어딘가에서 사용될 수 있습니다. 나는 프레임을위한 'release'가 있는지 확신하지 못한다. (폼과 비슷하다.) 그런 식으로해야한다. –

답변

2

+1 모두에게 감사드립니다. 특히 Abelisto et Jeroen에게 감사드립니다. 이제 모든 문제를 해결했습니다. Abelisto가 PostMessage를 제안 할 때까지 나는 많은 오류가 발생했습니다. 전체 솔루션은 울부 짖는 소리입니다 :

첫 번째 프레임 또는 frmMain 수 다음과 같은 프레임에 관련된

const WM_MY_MESSAGE = WM_USER + 0; 
type 
TfraMain = class(TFrame) 
... 
private 
    FFraChild  : TFraChild;//second frame 
    procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE; 
    procedure ComingBackFromFrame(aFrame:TFrame); 
.... 
//step when the second frame is created 
    FFraChild := TFraChild.Create(Application); 
    with FFraChild do 
    begin 
    GoBack:= ComingBackFromFrame; 
    parent:=Self; 
    Show; 
    end; //with 
.... 
procedure TfraMain.ComingBackFromFrame(aFrame:TFrame); 
begin 
if aFrame<>nil then 
begin 
try 
    aFrame.Hide; 
    PostMessage(Self.Handle,WM_MY_MESSAGE,0,0); 
    except on e:Exception do 
// log error 
    end; 
end; 
end; 

procedure TfraMain.OnMyMessage(var Msg: TMessage); 
begin 
FreeAndNil(FFraChild); 
end; 

초 프레임 또는 프레임 '아이'

type 
    TCallBack = procedure(aFrame:TFrame) of object; 

    TFraChild = class(TFrame) 
... 
    private 
    FGoBack:TCallBack; 
    public 
    property GoBack:TCallBack read FGoBack write FGoBack; 
.... 
//after all operations with it are finished 
if Assigned(fgoback) then 
    FGoBack(Self); 

@Jeroen, 내가 발견하지 않았다 무엇인가 TForm의 구현에 존재하는 'Release'.

안부,
라두

+1

+1하여 문제를 해결하십시오. 당신의 정보를 위해서 :'Release'는'PostMessage' 메카니즘을 사용합니다. –

+0

지금 누가 받아 들일만한 자격이 있는지 :)) 당신은 나에게 부분적인 해결책을 주었고 Abelisto와 CodeInChaos는 다른 부분을 .... – RBA

3

당신은 CommingBackFromFrame입니다. 따라서 반환 유형이 TCallBack 인 경우를 제외하고는 컴파일되지 않습니다.

GoBack에 구독하는 대신 GoBack:=CommingBackFromFrame;을 구독하고 싶을 수 있습니다. 또는 CommingBackFromFrame이 선언 된 지역에 따라 GoBack:=wFrm.CommingBackFromFrame; 일 수도 있습니다.

(!) 참고 : 당신은, 단어는 "오는"와 CommingBackFromFrame에서 오는 그것이 무엇을 어디에하지 comming

+0

나는 '오는'방법의 선언을 포함하도록 질문을 편집했다. – RBA

2

지정되어 오타가; 그것 없이는 CodeInChaos` answer을 얻을 수 있습니다.

wFrmDblDet의 일부입니까, 아니면 포괄 범위입니까 (with의 사용법으로 인해 흐리게 처리됩니까?)?

현재 코드에서 ComingBackFromFrame(wFrm)TCallBack을 반환해야하지만 이는 사용자의 의도가 아니라고 생각합니다.

- 제로

+0

감사합니다. 내가 작업을 마친 후 두 번째 프레임을 해제하고 싶습니다. – RBA

4

이것은 아주 나쁜 습관입니다 - 객체를 자체 코드에서 제거하십시오. PostMessage()를 통해 메시지 처리기로이를 수행하여 VCL이 객체를 해제하기 전에 모든 작업을 완료했는지 확인하십시오. 이 같은
뭔가 :

TFrameType = class(TFrame) 
protected 
    procedure FreeMe(var Msg TMessage) message WM_FREE_MY_FRAME; 
public 
    procedure PostponedFree; 
end; 

procedure TFrameType.FreeMe(var Msg TMessage); 
begin 
    Free; 
end; 

procedure TFrameType.PostponedFree; 
begin 
    PostMessage(Self.Handle, WM_FREE_MY_FRAME, 0, 0); 
end; 

그리고 PostponedFree를 호출합니다. PS 코드가 정확하지 않을 수 있습니다 - 지금 델파이를 시작하지 않았습니다. 죄송합니다.

+0

예, 좋지 않은 생각입니다. 너무 피곤해서 코드 작성이 필요할 때 일어나는 일입니다. 불행히도, 저는 +2 할 수 없습니다 .... :) 고마워요. – RBA

+0

또는 그 용도로 정확히 추가 된 릴리스 방법이 있습니다. – dummzeuch

관련 문제