📄 error.cpp
字号:
{
case DBBINDSTATUS_OK:
break;
//Display BindStatus Error to the user...
default:
{
iSelect = wMessageBox(hWnd, MB_TASKMODAL | MB_ICONERROR | MB_OKCANCEL, wsz_ERROR,
L"Accessor BindStatus Errors:\n"
L"rgBindings[%d]\n\n"
L"iOrdinal = %d\n"
L"wType = %s\n"
L"cbMaxLen = %d\n"
L"bPrecision = %d\n"
L"bScale = %d\n\n"
L"DBBINDSTATUS = %S",
i,
rgBindings[i].iOrdinal,
GetDBTypeName(rgBindings[i].wType),
rgBindings[i].cbMaxLen,
rgBindings[i].bPrecision,
rgBindings[i].bScale,
GetMapName(rgStatus[i], NUMELE(g_rgBindStatusMap), g_rgBindStatusMap)
);
if(iSelect == IDCANCEL)
goto CLEANUP;
break;
}
}
}
CLEANUP:
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayPropErrors
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayPropErrors(HWND hWnd, ULONG cPropSets, DBPROPSET* rgPropSets)
{
//Display a dialog with the affending properties...
HRESULT hr = S_OK;
INT iSelect = 0;
for(ULONG i=0; i<cPropSets; i++)
{
for(ULONG j=0; j<rgPropSets[i].cProperties; j++)
{
DBPROPSET* pPropSet = &rgPropSets[i];
DBPROP* pProp = &pPropSet->rgProperties[j];
if(pProp->dwStatus != DBPROPSTATUS_OK)
{
WCHAR wszBuffer[MAX_NAME_LEN+1];
CHAR szPropSet[MAX_NAME_LEN+1];
CHAR* pszPropSet = GetPropSetName(pPropSet->guidPropertySet);
if(pszPropSet == NULL)
{
StringFromGUID2(pPropSet->guidPropertySet, wszBuffer, MAX_NAME_LEN);
ConvertToMBCS(wszBuffer, szPropSet, MAX_NAME_LEN);
pszPropSet = szPropSet;
}
//Find property Value
wszBuffer[0] = wEOL;
VariantToString(&pProp->vValue, wszBuffer, MAX_NAME_LEN, CONV_VARBOOL);
//Append the Error
iSelect = wMessageBox
(
hWnd, MB_TASKMODAL | MB_ICONERROR | MB_OKCANCEL, wsz_ERROR,
L"Properties in Error:\n"
L"rgPropSets[%d].rgProperties[%d]\n\n"
L"guidPropertySet\t= %S\n"
L"dwPropertyID\t= %S (0x%x)\n"
L"dwOptions\t\t= %s\n"
L"vValue.vt\t\t= %S\n"
L"vValue\t\t= %s\n\n"
L"dwStatus\t\t= %s",
i,j,
pszPropSet,
GetPropertyName(pProp->dwPropertyID, pPropSet->guidPropertySet),
pProp->dwPropertyID,
pProp->dwOptions == DBPROPOPTIONS_REQUIRED ? L"DBPROPOPTIONS_REQUIRED" : L"DBPROPOPTIONS_OPTIONAL",
GetVariantTypeName(V_VT(&pProp->vValue)),
wszBuffer,
GetMapName(pProp->dwStatus, NUMELE(g_rgPropStatusMap), g_rgPropStatusMap)
);
if(iSelect == IDCANCEL)
goto CLEANUP;
}
}
}
CLEANUP:
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayPropErrors
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayPropErrors(HWND hWnd, SOURCE ePropSource, IUnknown* pIUnknown)
{
ASSERT(pIUnknown);
//GetProperties with DBPROPSET_PROPERTIESINERROR.
HRESULT hr = S_OK;
ULONG cPropSets = 0;
DBPROPSET* rgPropSets = NULL;
IDBProperties* pIDBProperties = NULL;
ICommandProperties* pICommandProperties = NULL;
//Setup input DBPROPSET_PROPERTIESINERROR
const ULONG cPropertyIDSets = 1;
DBPROPIDSET rgPropertyIDSets[cPropertyIDSets];
rgPropertyIDSets[0].guidPropertySet = DBPROPSET_PROPERTIESINERROR;
rgPropertyIDSets[0].cPropertyIDs = 0;
rgPropertyIDSets[0].rgPropertyIDs = NULL;
//ICommand::GetProperties
switch(ePropSource)
{
case DATASOURCE:
{
XTESTC(hWnd, hr = pIUnknown->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties));
XTESTC(hWnd, hr = pIDBProperties->GetProperties(cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets));
break;
}
case COMMAND:
{
XTESTC(hWnd, hr = pIUnknown->QueryInterface(IID_ICommandProperties, (void**)&pICommandProperties));
XTESTC(hWnd, hr = pICommandProperties->GetProperties(cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets));
break;
}
default:
ASSERT(!"Unhandled Type!");
break;
};
//Now delegate to display all properties in error
XTESTC(hWnd, hr = DisplayPropErrors(hWnd, cPropSets, rgPropSets));
CLEANUP:
FreeProperties(&cPropSets, &rgPropSets);
SAFE_RELEASE(pICommandProperties);
SAFE_RELEASE(pIDBProperties);
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayRefCountErrors
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayRefCountErrors(HWND hWnd, CHAR* pszName, ULONG ulActRefCount, ULONG ulExpRefCount)
{
ASSERT(pszName);
//Display RefCount difference...
if(ulActRefCount != ulExpRefCount && GetErrorPosting(EP_REFCOUNT_FAILURE))
{
wMessageBox
(
hWnd,
MB_TASKMODAL | MB_ICONERROR | MB_OK,
wsz_ERROR,
L"%S\n"
L"RefCount = %d, Expected = %d",
pszName,
ulActRefCount,
ulExpRefCount
);
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayAllErrors
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayAllErrors(HWND hWnd, HRESULT hrActual, WCHAR* pwszFile, ULONG ulLine)
{
//Delegate
if(FAILED(hrActual) || GetErrorPosting(EP_ERRORINFO_ALWAYS) || GetErrorPosting(EP_HRESULT_ALWAYS))
DisplayAllErrors(hWnd, hrActual, hrActual, pwszFile, ulLine);
return hrActual;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayAllErrors
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayAllErrors(HWND hWnd, HRESULT hrActual, HRESULT hrExpected, WCHAR* pwszFile, ULONG ulLine)
{
//By Default we only worry about ErrorInfo if(FAILED(hr))
//But we may want to worry about it at other times as well?
if((FAILED(hrActual) || (hrActual!=hrExpected) || GetErrorPosting(EP_ERRORINFO_ALWAYS)) &&
!GetErrorPosting(EP_ERRORINFO_NEVER))
{
if(DisplayAllErrorInfo(hWnd, pwszFile, ulLine)==S_OK)
{
//We had ErrorInfo, no need to display error info
//Unless the user has something other than NOERRORINFO selected
if(GetErrorPosting(EP_HRESULT_NOERRORINFO))
goto CLEANUP;
}
}
//If not available, display MSG Box with info
if((FAILED(hrActual) || (hrActual!=hrExpected) || (hrActual!=S_OK && GetErrorPosting(EP_HRESULT_ALWAYS))) &&
!GetErrorPosting(EP_HRESULT_NEVER))
{
//Display the HRESULT
DisplayHRESULT(hWnd, hrActual, pwszFile, ulLine);
}
CLEANUP:
if(hrActual!=hrExpected && SUCCEEDED(hrActual))
return E_FAIL;
return hrActual;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayHRESULT
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayHRESULT(HWND hWnd, HRESULT hrActual, WCHAR* pwszFile, ULONG ulLine)
{
//display the Error
wMessageBox(hWnd, MB_TASKMODAL | MB_ICONERROR | MB_OK, wsz_ERROR,
L"Interface: %s\nResult: 0x%08x = %s\n\nFile: %s\nLine: %d", L"Unknown", hrActual, GetErrorName(hrActual), pwszFile, ulLine);
return hrActual;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayAllErrorInfo
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayAllErrorInfo(HWND hWnd, WCHAR* pwszFile, ULONG ulLine)
{
ULONG cRecords = 0;
IErrorRecords* pIErrorRecords = NULL;
HRESULT hr = S_OK;
//Try to display Extened ErrorInfo
if((hr = GetErrorRecords(hWnd, &cRecords, &pIErrorRecords))==S_OK && cRecords)
{
DisplayErrorRecords(hWnd, cRecords, pIErrorRecords, pwszFile, ulLine);
SAFE_RELEASE(pIErrorRecords);
}
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT GetErrorRecords
//
// Get the error message generated by an OLE DB object
/////////////////////////////////////////////////////////////////////////////
HRESULT GetErrorRecords(HWND hWnd, ULONG* pcRecords, IErrorRecords** ppIErrorRecords)
{
ASSERT(pcRecords && ppIErrorRecords);
HRESULT hr;
//NULL output params
*pcRecords = 0;
*ppIErrorRecords = NULL;
ISupportErrorInfo* pISupportErrorInfo = NULL;
IErrorInfo* pIErrorInfo = NULL;
//See if this interface supports ErrorInfo
//If not there is no reason to display any error
if((hr = GetErrorInfo(0, &pIErrorInfo))==S_OK && pIErrorInfo)
{
//IErrorRecords may not be supported on the existing error object.
//Some other things could have posted an error object (VB) for example...
TESTC(hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void**)ppIErrorRecords));
XTESTC(hWnd, hr = (*ppIErrorRecords)->GetRecordCount(pcRecords));
}
CLEANUP:
SAFE_RELEASE(pISupportErrorInfo);
SAFE_RELEASE(pIErrorInfo);
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT GetSqlErrorInfo
//
// Get the error message generated by an OLE DB object
/////////////////////////////////////////////////////////////////////////////
HRESULT GetSqlErrorInfo(ULONG iRecord, IErrorRecords* pIErrorRecords, BSTR* pBstr, LONG* plNativeError)
{
ASSERT(pBstr);
HRESULT hr = S_OK;
ISQLErrorInfo* pISQLErrorInfo = NULL;
LONG lNativeError = 0;
//Get the Error Records
if(pIErrorRecords)
{
//If there is ErrorInfo, GetSQLInfo for the desired record
//ISQLErrorInfo is not mandatory
TESTC(hr = pIErrorRecords->GetCustomErrorObject(iRecord, IID_ISQLErrorInfo, (IUnknown**)&pISQLErrorInfo));
//If there was a CustomErrorObject
if(pISQLErrorInfo)
hr = pISQLErrorInfo->GetSQLInfo(pBstr, &lNativeError);
}
CLEANUP:
if(plNativeError)
*plNativeError = lNativeError;
SAFE_RELEASE(pISQLErrorInfo);
return hr;
}
////////////////////////////////////////////////////////////////////////
// HRESULT DisplayErrorRecords
//
/////////////////////////////////////////////////////////////////////////////
HRESULT DisplayErrorRecords(HWND hWnd, ULONG cRecords, IErrorRecords* pIErrorRecords, WCHAR* pwszFile, ULONG ulLine)
{
HRESULT hr = S_OK;
IErrorInfo* pIErrorInfo = NULL;
BSTR bstrDescription = NULL;
BSTR bstrSource = NULL;
BSTR bstrSQLInfo = NULL;
INT iSelect = 0;
static LCID lcid = GetSystemDefaultLCID();
//Get the Error Records
if(cRecords && pIErrorRecords)
{
LONG lNativeError = 0;
ERRORINFO ErrorInfo;
//Loop through the records
for(ULONG i=0; i<cRecords; i++)
{
//GetErrorInfo
XTESTC(hWnd, hr = pIErrorRecords->GetErrorInfo(i,lcid,&pIErrorInfo));
//Get the Description
XTESTC(hWnd, hr = pIErrorInfo->GetDescription(&bstrDescription));
//Get the Source - this will be the window title...
XTESTC(hWnd, hr = pIErrorInfo->GetSource(&bstrSource));
//Get the Basic ErrorInfo
XTESTC(hWnd, hr = pIErrorRecords->GetBasicErrorInfo(i,&ErrorInfo));
//Get the SQL Info
GetSqlErrorInfo(i, pIErrorRecords, &bstrSQLInfo, &lNativeError);
//Display the Error
if(bstrSQLInfo)
iSelect = wMessageBox(hWnd, MB_TASKMODAL | MB_ICONERROR | MB_OKCANCEL, bstrSource ? bstrSource : wsz_ERRORINFO, L"Interface: %S\nResult: 0x%08x = %s\n\nISQLErrorInfo: [%s][0x%08x]\n\nSource: \"%s\"\nIErrorInfo: [0x%08x] \"%s\"\n\nFile: %s\nLine: %d", GetInterfaceName(ErrorInfo.iid), ErrorInfo.hrError, GetErrorName(ErrorInfo.hrError), bstrSQLInfo, lNativeError, bstrSource, ErrorInfo.dwMinor, bstrDescription, pwszFile, ulLine);
else
iSelect = wMessageBox(hWnd, MB_TASKMODAL | MB_ICONERROR | MB_OKCANCEL, bstrSource ? bstrSource : wsz_ERRORINFO, L"Interface: %S\nResult: 0x%08x = %s\n\nSource: \"%s\"\nIErrorInfo: [0x%08x] \"%s\"\n\nFile: %s\nLine: %d", GetInterfaceName(ErrorInfo.iid), ErrorInfo.hrError, GetErrorName(ErrorInfo.hrError), bstrSource, ErrorInfo.dwMinor, bstrDescription, pwszFile, ulLine);
SAFE_RELEASE(pIErrorInfo);
SAFE_SYSFREE(bstrDescription);
SAFE_SYSFREE(bstrSource);
SAFE_SYSFREE(bstrSQLInfo);
if(iSelect == IDCANCEL)
goto CLEANUP;
}
}
CLEANUP:
SAFE_RELEASE(pIErrorInfo);
SAFE_SYSFREE(bstrDescription);
SAFE_SYSFREE(bstrSource);
SAFE_SYSFREE(bstrSQLInfo);
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -