GME  13
mfcdual.cpp
Go to the documentation of this file.
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 }