1. CoClass 에서 public ISupportErrorInfo 에러핸들링 클래스를 상속받고 있는 상태.
에러핸들링 구현부에서 빨간색 부분을 주석처리한ㄷㅏ
STDMETHODIMP CProbe::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IProbe
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
// if (InlineIsEqualGUID(*arr[i],riid)) 없애야 메세지가 잘 전달되더라..// 안 없애면 에러메세지가 0000000000 같은 다른 메세지가 날라온다.
return S_OK;
}
return S_FALSE;
}
2. 에러 핸들링을 하고 싶은 곳에 한다.
STDMETHODIMP CProbe::StarGate()
{if( m_nMineral < 100 || m_nGas < 50 )
{/// 에러발생시키는 부분. Copy & Past!
HRESULT hr;
// 에러 정보 채우기 위한 인터페이스 객체 생성
CComPtr<ICreateErrorInfo> pCreateErrInfo;
// 에러 지정
CComQIPtr<IErrorInfo, &IID_IErrorInfo> pErrInfo;
// 1. OleAuto32.dll에 구현되어 있는 함수로써 에러
// 정보 개체를 생성
hr = ::CreateErrorInfo(&pCreateErrInfo);
if(SUCCEEDED(hr))
{
// 2. 인터페이스 메서드를 사용하여 생성된 에러
// 정보 개체에 에러 정보 저장
// 에러가 발생한 자동화 개체
// 일반적으로 ProgID가 지정된다.
pCreateErrInfo->SetSource(
OLESTR("Probe.Probe.1")); // 알맞게 이름 수정 ProgID 대충 넣는다.
// 에러에 대한 설명
pCreateErrInfo->SetDescription(
OLESTR("돈이 모자르다.")); // 발생할 에러메세지
pErrInfo = pCreateErrInfo;
// 3. 에러 정보 개체를 스레드와 연결함
::SetErrorInfo(0, pErrInfo);
}
return E_INVALIDARG;}//if
else
{
m_nMineral -= 100;
m_nGas -= 50;
}
return S_OK;
}
===============클라이언트에서 사용법===============
1. 에러를 출력할 함수 추가
void CATL_COM_PROBE_CLIENTDlg::ShowMessage(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
CString szMsg = "에러가 발생했습니다.\n";
CString szTemp;
szTemp.Format("에러 코드 : %081x\n", e.Error());
szMsg += szTemp;
szTemp.Format("에러 내용 : %s\n", e.ErrorMessage());
szMsg += szTemp;
szTemp.Format("에러 소스 : %s\n",
bstrSource.length() ? (LPCTSTR)bstrSource :
_T("없슴"));
szMsg += szTemp;
szTemp.Format("에러 설명 : %s\n",
bstrDescription.length() ? (LPCTSTR)bstrDescription :
_T("없슴"));
szMsg += szTemp;
AfxMessageBox(szMsg);
}
2. 에러 캐취~
try
{
ptrIBuild->StarGate();
}
catch (_com_error& e){
ShowMessage(e);
return;
}