⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 error.cpp

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		{
			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 + -