[팁] OnException을 이용한 Exception처리
// 볼랜드 포럼의 장성호 님의 글의 내용을 보고 정리한 것입니다..
// 이런것도 있는지 오늘 알았습니다.. 장성호님께 감사의 뜻을 전합니다!!
========================================================================================================
보통 우리가 Exception처리르 할경우 try~catch로 예상 부분 혹은 발생 부분에 대해서..
Exception 처리를 한다. 그렇지만, 모든 Case에 대한 Exception 처리는 불가능하다..
예측하지 못한 Case들이 너무나도 많으므로..
현재 CodeGear의 C++ Builder와 Delphi에서는 해당 Application (폼, 컨트롤)등에서 발생하는...
모든 Exception에 대해서 핸들링 할수 있는 방법이 존재한다..
TApplication의 OnException이벤트 핸들러를 이용하는 방법이다.
OnException 핸들러의 타입은 아래와 같다.
이러한 OnException 핸들러는 TApplication->HandleException에서 호출합니다.
1) TCustomForm에서 예외 발생시 Application.HandleException을 호출합니다.
2) TWinControl의 MainWndProc에서 WindowProc를 호출해주고 예외가 발생하면 Application.HandleException을 호출합니다.
3) TDragObject의 WndProc와 MainWndProc에서 예외발생시 Application.HandleException을 호출합니다.
4) TDataModule의 HandleCreateException 와 DoDestroy 에서 예죄발생시 호출합니다.
5) 기타 StdCtrls , ComCtrls , ExtCtrls 등의 각종 Control및 Component에서도 예외발생시 호출해주는 곳이 많습니다. Timer 또는 ADOConnection등의 Component에서도 호출합니다.
위의 내용은 HandleException을 호출해주는 곳입니다.
GraphicControl의 WndProc에서는 Application.HandleException 을 직접 호출하지는 않습니다.
만약 GraphicControl의 WndProc에서 예외가 발생하면 해당 GraphicControl이 소속된 WinControl의 WindowProc에서 except가 잡혀서 거기서 Application.HandleException가 호출됩니다.
=> 이경우 GraphicControl의 이벤트 핸들러(MouseDown/Move/Up등)에서 예외가 발생하더라도
Application.OnException으로 넘어오는 Sender가 GraphicControl이 아니라
Parent인 WinControl이 Sender가 될것입니다.
TPopupMenu , TMenuItem에서 예외발생시 PopupList가 Application.HandleException을 호출한다.
Action은 Application.OnIdle에서 호출하므로 예외발생 객체도 모두 Application이 된다.
사용하는 예~!!
//프로그램 시작시 Application->OnException 이벤트 핸들러를 걸어준다.
Application->OnException = AppException;
}
//---------------------------------------------------------------------------
void __fastcall TForm1: : AppException( System: : TObject* Sender, Sysutils: : Exception* E)
{
String sObj = "" ;
if ( Sender)
{
if ( Sender->InheritsFrom( __classid( TControl) ) )
{
TControl * ctrl= ( TControl * ) Sender;
while ( ctrl)
{
sObj = ctrl->Name+ " -> " + sObj;
ctrl = ctrl->Parent;
}
}
else if ( Sender->InheritsFrom( __classid( TComponent) ) )
{
TComponent * Comp= ( TComponent * ) Sender;
sObj = Comp->Name;
if ( Comp->Owner)
{
sObj = Comp->Owner->Name + " -> " + sObj;
}
}
}
String sExpMsg = sObj + " Msg:" + E->Message;
//Log를 저장하거나.. SaveLog ..
//필요에 따라 메세지를 뿌려준다.
E->Message = sExpMsg;
Application->ShowException ( E) ;
}