2011-01-29 2 views
1

Я считаю, что я слишком устал, и я не понимаю, почему небольшой обратный вызов не работает. У меня есть 2 кадра, созданных динамически, я показываю первый и одним щелчком показываю второй. Когда я закончу работу со вторым, я хочу показать первый кадр и освободить второй кадр. Кодекс ниже:Delphi - callback неправильный код

код для первого кадра:

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

Он никогда не мудрая вещь, чтобы освободить параметр метода события; базовый объект все еще может использоваться где-то в стеке вызовов. Я не уверен, что есть «релиз» для фреймов (например, для форм), но вы должны сделать что-то подобное. –

ответ

2

+1 всем. Благодарю вас за ответы, особенно для Abelisto et Jeroen. Я решил все проблемы. Пока Абелисто не предложил 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, я не нашел что-то связано с Frames, к которой «Release», существующий в реализации TForm.

С наилучшими пожеланиями,
Radu

+1

+1 для решения вашей проблемы. Для вашей информации: 'Release' также использует механизм PostMessage. –

+0

теперь, кто заслуживает принятия :)), вы дали мне частичное решение, а Abelisto и CodeInChaos другую часть .... – RBA

3

Вы звоните CommingBackFromFrame. Поэтому, если он не является возвращаемым типом TCallBack, очевидно, что он не компилируется.

Возможно, вы захотите сделать GoBack:=CommingBackFromFrame;, который подписывает метод CommingBackFromFrame на четный GoBack. Или, возможно, GoBack:=wFrm.CommingBackFromFrame; в зависимости от того, где объявляется CommingBackFromFrame.

Sidenote: У вас есть опечатка, слово «идет», а не comming

+0

Я отредактировал вопрос, чтобы содержать объявление метода 'coming'. – RBA

2

Укажите, где CommingBackFromFrame приходит и то, что он делает; без этого, CodeInChaos` answer - это лучшее, что вы можете получить.

Это часть wFrmDblDet, или часть вашего охвата (использование with обфускации)?

В вашем текущем коде ComingBackFromFrame(wFrm) должен вернуть TCallBack, но я думаю, что это было не ваше намерение.

--jeroen

+0

Спасибо, Jeroen. Я хочу освободить второй кадр после того, как я закончу работать с ним. – RBA

4

BTW это плохая практика - освободить объект из своего собственного кода. Попытайтесь сделать это обработчиком сообщений через 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 может быть неточным - я не начал Delphi сейчас. Сожалею.

+0

Да, плохая идея. Это то, что происходит, когда я слишком устал и все еще нуждаюсь в коде. К сожалению, я не могу сделать +2 .... :) Спасибо. – RBA

+0

В качестве альтернативы существует метод Release, который был добавлен именно для этой цели. – dummzeuch

Смежные вопросы