GME
13
|
00001 // mfcdual.cpp: Helpful functions for adding dual interface support to 00002 // MFC applications 00003 00004 // This is a part of the Microsoft Foundation Classes C++ library. 00005 // Copyright (c) Microsoft Corporation. All rights reserved. 00006 // 00007 // This source code is only intended as a supplement to the 00008 // Microsoft Foundation Classes Reference and related 00009 // electronic documentation provided with the library. 00010 // See these sources for detailed information regarding the 00011 // Microsoft Foundation Classes product. 00012 00013 #include "stdafx.h" 00014 00015 #include <afxpriv.h> 00016 00017 #ifdef _DEBUG 00018 #define new DEBUG_NEW 00019 #undef THIS_FILE 00020 static char THIS_FILE[] = __FILE__; 00021 #endif 00022 00024 // DualHandleException 00025 00026 HRESULT DualHandleException(REFIID riidSource, const CException* pAnyException) 00027 { 00028 ASSERT_VALID(pAnyException); 00029 00030 TRACE0("DualHandleException called\n"); 00031 00032 // Set ErrInfo object so that VTLB binding container 00033 // applications can get rich error information. 00034 ICreateErrorInfo* pcerrinfo; 00035 HRESULT hr = CreateErrorInfo(&pcerrinfo); 00036 if (SUCCEEDED(hr)) 00037 { 00038 TCHAR szDescription[256]; 00039 LPCTSTR pszDescription = szDescription; 00040 GUID guid = GUID_NULL; 00041 DWORD dwHelpContext = 0; 00042 BSTR bstrHelpFile = NULL; 00043 BSTR bstrSource = NULL; 00044 if (pAnyException->IsKindOf(RUNTIME_CLASS(COleDispatchException))) 00045 { 00046 // specific IDispatch style exception 00047 COleDispatchException* e = (COleDispatchException*)pAnyException; 00048 00049 guid = riidSource; 00050 hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 00051 (e->m_wCode + 0x200)); 00052 00053 pszDescription = e->m_strDescription; 00054 dwHelpContext = e->m_dwHelpContext; 00055 00056 // propagate source and help file if present 00057 // call ::SysAllocString directly so no further exceptions are thrown 00058 if (!e->m_strHelpFile.IsEmpty()) { 00059 CT2COLE strHelpFile(e->m_strHelpFile); 00060 bstrHelpFile = ::SysAllocString(strHelpFile); 00061 } 00062 if (!e->m_strSource.IsEmpty()) { 00063 CT2COLE strSource(e->m_strSource); 00064 bstrSource = ::SysAllocString(strSource); 00065 } 00066 00067 } 00068 else if (pAnyException->IsKindOf(RUNTIME_CLASS(CMemoryException))) 00069 { 00070 // failed memory allocation 00071 AfxLoadString(AFX_IDP_FAILED_MEMORY_ALLOC, szDescription); 00072 hr = E_OUTOFMEMORY; 00073 } 00074 else 00075 { 00076 // other unknown/uncommon error 00077 AfxLoadString(AFX_IDP_INTERNAL_FAILURE, szDescription); 00078 hr = E_UNEXPECTED; 00079 } 00080 00081 if (bstrHelpFile == NULL && dwHelpContext != 0) { 00082 CT2COLE strHelpFilePath(AfxGetApp()->m_pszHelpFilePath); 00083 bstrHelpFile = ::SysAllocString(strHelpFilePath); 00084 } 00085 00086 if (bstrSource == NULL) { 00087 CT2COLE strAppName(AfxGetAppName()); 00088 bstrSource = ::SysAllocString(strAppName); 00089 } 00090 00091 // Set up ErrInfo object 00092 pcerrinfo->SetGUID(guid); 00093 pcerrinfo->SetDescription(const_cast<LPOLESTR>(pszDescription)); 00094 pcerrinfo->SetHelpContext(dwHelpContext); 00095 pcerrinfo->SetHelpFile(bstrHelpFile ? bstrHelpFile : L""); 00096 pcerrinfo->SetSource(bstrSource ? bstrSource : L""); 00097 00098 TRACE("\tSource = %ws\n", bstrSource); 00099 TRACE("\tDescription = %s\n", pszDescription); 00100 TRACE("\tHelpContext = %lx\n", dwHelpContext); 00101 TRACE("\tHelpFile = %ws\n", bstrHelpFile); 00102 00103 // Set the ErrInfo object for the current thread 00104 IErrorInfo* perrinfo; 00105 if (SUCCEEDED(pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID*)&perrinfo))) 00106 { 00107 SetErrorInfo(0, perrinfo); 00108 perrinfo->Release(); 00109 } 00110 00111 pcerrinfo->Release(); 00112 } 00113 00114 TRACE("DualHandleException returning HRESULT %lx\n", hr); 00115 00116 return hr; 00117 }