Debugging Note/FireMonkey [C++ Builder]

Form과 Frame 화면구성시 발생할 수 있는 Back 버튼 문제 해결

klisty 2015. 1. 30. 13:59

안드로이드에선 Activity라는 것이 있다. 그와 대응하는 것이 바로 Firemonkey에선 Form이다.

그리고 최근(이라고 하지만 2년전이었나. 3년 전이었나?)에 안드로이드에선 Fragment라는 것이 도입되었다.

이것의 대응은 Firemonkey에선 MultiView와 Frame이다.


아무튼 어플리케이션을 만들다 보면 Form은 하나로 놓고, Frame을 다수로 만들어 Module화를 시도하는 경우가 있는데, 이러면 Form을 여러개 만들 때와는 다른 현상이 생기게 된다.


Form으로 각 화면들을 구성하였다면 Form1->BringToFront(); 와 같은 형대로 Form위에 오버뷰 시키기 때문에 뒤로가기버튼(Back Key)을 누르면 이전 Form이 불려와서 문제없이 동작되게 된다. 하지만 Frame으로 만들게 되면 처음부터 떠 있던 것이 Form1밖에 없어서 뒤로가기를 하여도 어플리케이션이 이전 Frame으로 가는 것이 아니라 바로 종료가 되어 버린다.


결국 이를 해결하기 위해선 Frame이 불려온 순서를 기억 할 수 밖에 없고 이를 위해 List를 사용하여 각각의 포인터를 기억하도록 시켰다.




[ Form1.h ] 

__published: // IDE-managed Components

void __fastcall FormKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar,

 TShiftState Shift);   <- 이건 Form에서 Event를 추가 하면 된다.


private: // User declarations

// frame의 생성 순서 기억

TList  *FrameList;


public: // User declarations

// Frame 순서와 관련된 함수

void* __fastcall FrameListCurrent(void);

int    __fastcall FrameListAdd(TFrame *ptFrame);

bool  __fastcall FrameListDelete(void);




[ Form1.cpp ]

void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar,

 TShiftState Shift)

{

if( Key == vkHardwareBack ){

// key값 초기화

Key = 0;


ButtonMainPrevClick(Sender);  <-- 이건 구지 이렇게 할 필요 없다.

}

}

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonMainPrevClick(TObject *Sender)

{

if( Form1->FrameListCurrent() ==  Frame1 ){

struct TCloseDialogHandler : public TCppInterfacedObject<TInputCloseDialogProc> {

void __fastcall Invoke(const System::Uitypes::TModalResult AResult) {

switch (AResult) {

case mrYes :

 Form1->Close();

break;

case mrNo:

return;

break;

}

}

};

_di_TInputCloseDialogProc HandlerMessageDlgExit = new TCloseDialogHandler();


MessageDlg("Do you want to exit? really?",

  TMsgDlgType::mtCustom,

  TMsgDlgButtons() << TMsgDlgBtn::mbNo << TMsgDlgBtn::mbYes , 0, HandlerMessageDlgExit);

}

else{

Form1->FrameListDelete();

}

}

//---------------------------------------------------------------------------

//---------------------------------------------------------------------------


int __fastcall TForm1::FrameListAdd(TFrame *ptFrame)

{

FrameList->Add(ptFrame);

return 0;

}

//---------------------------------------------------------------------------


bool __fastcall TForm1::FrameListDelete(void)

{

((TFrame*)FrameList->Last())->Parent = NULL;

((TFrame*)FrameList->Last())->Visible = false;


FrameList->Delete( FrameList->Count - 1 );


((TFrame*)FrameList->Last())->BringToFront();


return True;

}

//---------------------------------------------------------------------------


void* __fastcall TForm1::FrameListCurrent(void)

{

return FrameList->Last();

}

//---------------------------------------------------------------------------