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

📄 axrecordset.cpp

📁 一个非常好用的ADO封装类,程序员不再需要跟烦人的COM接口打交道,写数据库程序不再麻烦!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Return: The current sort string.
//
LPCTSTR CAxRecordset::Sort(LPCTSTR lpszSort)
{
	VALID_ADO_OBJECT(m_piRecordset);
  HRESULT hr = S_OK;

  if ( lpszSort )
  {
    hr = m_piRecordset->put_Sort(_bstr_t(lpszSort));
	  if FAILED( hr )
	    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Sort"), hr);
  }

  BSTR bstrSort;
  hr = m_piRecordset->get_Sort(&bstrSort);
  if FAILED( hr )
	  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Sort"), hr);

#ifdef _UNICODE
  return (_bstr_t(bstrSort).operator const wchar_t *());
#else
  return (_bstr_t(bstrSort).operator const char*());
#endif
}

// Method: Source
//   Desc: Set/Return the Source property for the recordset.
//
//   Args: lpszSource
//          Sets/Returns the source for the recordset data.
//          Typically the source is specified in the Open
//          method.
//
// Return: The current data source.
//
LPCTSTR CAxRecordset::Source(LPCTSTR lpszSource)
{
	VALID_ADO_OBJECT(m_piRecordset);
  HRESULT hr = S_OK;

  if ( lpszSource  && !_IsOpen() )
  {
    hr = m_piRecordset->put_Source(_bstr_t(lpszSource));
	  if FAILED( hr )
	    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Source"), hr);
  }

  _variant_t vtSource;
  hr =  m_piRecordset->get_Source(&vtSource);
  if FAILED( hr )
	  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Source"), hr);

#ifdef _UNICODE
  return (_bstr_t(vtSource.bstrVal).operator const wchar_t *());
#else
  return (_bstr_t(vtSource.bstrVal).operator const char *());
#endif
}

ObjectStateEnum CAxRecordset::State()
{
	VALID_ADO_OBJECT(m_piRecordset);
	long lState;

  HRESULT hr = m_piRecordset->get_State(&lState);
	if FAILED( hr )
	  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::State"), hr);

	return ((ObjectStateEnum)lState);
}

RecordStatusEnum CAxRecordset::Status()
{
	VALID_ADO_OBJECT(m_piRecordset);
	long lStatus;

  HRESULT hr = m_piRecordset->get_Status(&lStatus);
	if FAILED( hr )
	  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Status"), hr);

	return ((RecordStatusEnum)lStatus);
}


long CAxRecordset::FieldCount()
{
	VALID_ADO_OBJECT(m_piRecordset);
	long lFieldCount;

	if FAILED( m_pFields->get_Count(&lFieldCount) )
		ThrowAxException(AXLIB_ERROR_NONE);

	return lFieldCount;
}




//----------------------------------------------------------
// Bookmark


//----------------------------------------------------------
// Utility


//----------------------------------------------------------
// Data Exchange
HRESULT CAxRecordset::_getADOField(LPCTSTR lpszColumn, ADOField** ppFld)
{
	VALID_ADO_OBJECT(m_piRecordset);
	ASSERT( m_pFields );

  return ( m_pFields->get_Item(_variant_t(lpszColumn), ppFld) );
}

HRESULT CAxRecordset::_isUpdatable(ADOField* pFld)
{
  long lAttrib = 0;
  HRESULT hr = pFld->get_Attributes(&lAttrib);

  if ( FAILED(hr) )
    return ( hr );

	//If both the adFldUpdatable (4) and adFldUnknownUpdatable (8)
	//flags are false, as is the case with an Identity field, then
	//we need to avoid an attempt to write data back to the field.
  //Returning the E_ACCESSDENIED value which, in this instance,
  //should not be considered an actual error needing to be handled.
	if ( !(lAttrib & adFldUpdatable) && !(lAttrib & adFldUnknownUpdatable) )
    hr = ERROR_ACCESS_DENIED;

  return ( hr );
}


_variant_t* CAxRecordset::_GetFieldValue(LPCTSTR lpszColumn)
{
  m_hr = _setGetFieldValue(false, lpszColumn, VT_VARIANT, NULL);

  if FAILED(m_hr)
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::_GetFieldValue"), m_hr);

  return (&m_vtData);
}

_variant_t* CAxRecordset::_GetFieldValue(long nColumn)
{
	VALID_ADO_OBJECT(m_piRecordset);
	ASSERT( m_pFields );
  ADOField* pFld = NULL;

  m_hr = m_pFields->get_Item(_variant_t(nColumn), &pFld);
  if ( FAILED(m_hr) )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::_GetFieldValue"), m_hr);

  m_vtData.Clear();
	m_vtData.vt = VT_ERROR;
	m_vtData.scode = DISP_E_PARAMNOTFOUND;

	m_hr = pFld->get_Value(&m_vtData);
  if ( FAILED(m_hr) )
  {
    m_vtData.Clear();
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::_GetFieldValue"), m_hr);
  }

  return (&m_vtData);
}

//------------------------------------------------------------------------
// Removed steps to set assumed values if the attempt to get a field
// value should fail. See revision notes under  v1.1.1 in AxLib.h.
HRESULT CAxRecordset::_getFldValue(ADOField* pFld, unsigned short varType, void** ppValue)
{
  HRESULT hr = S_OK;

  //If the table is empty or the field is empty
  //the variant's type is set to VT_NULL
  if ( _IsEmpty() )
  {
    m_vtData.vt = VT_NULL;
  }
  else
  {
    m_vtData.vt = VT_ERROR;
    m_vtData.scode = DISP_E_PARAMNOTFOUND;
    hr = pFld->get_Value(&m_vtData);
  }

  if ( *ppValue == NULL || (m_vtData.vt == VT_NULL) )
    return ( hr );

  if ( FAILED(hr) )
    return ( hr );

  switch ( varType )
  {
  case VT_I2 :
    (*(short*)*ppValue) = (short)m_vtData.iVal;
 //   (*(short*)*ppValue) = (m_vtData.vt == VT_NULL) ? 0 :
 //     (short)m_vtData.iVal;
    break;

  case VT_I4 :
      (*(int*)*ppValue) = (int)m_vtData.lVal;
 //   (*(int*)*ppValue) = (m_vtData.vt == VT_NULL) ? 0 :
 //     (int)m_vtData.lVal;
    break;

  case VT_I8 :
    (*(LONGLONG*)*ppValue) = (LONGLONG)(m_vtData.operator DECIMAL()).Lo64;
//    (*(LONGLONG*)*ppValue) = (m_vtData.vt == VT_NULL) ? 0 :
//      (LONGLONG)(m_vtData.operator DECIMAL()).Lo64;
    break;

  case VT_R4 : 
    (*(float*)*ppValue) = (float)m_vtData.fltVal;
//    (*(float*)*ppValue) = (m_vtData.vt == VT_NULL) ? 0L : 
//      (float)m_vtData.fltVal;
    break;

  case VT_R8 :
    (*(double*)*ppValue) = m_vtData.dblVal;
//    (*(double*)*ppValue) = (m_vtData.vt == VT_NULL) ? 0L :
//      m_vtData.dblVal;
    break;

  case VT_BOOL :
    (*(bool*)*ppValue) = (bool)(m_vtData.boolVal == -1);
 //   (*(bool*)*ppValue) = (m_vtData.vt == VT_NULL) ? false :
 //     (bool)(m_vtData.boolVal == -1);
    break;

  case VT_VARIANT :
    (*(_variant_t*)*ppValue) = m_vtData;
    break;

  case VT_BSTR :
//    if ( m_vtData.vt == VT_NULL )
//      ((CString*)*ppValue)->Empty();
//    else
      ((CString*)*ppValue)->operator =((LPCWSTR)m_vtData.bstrVal);
    break;

  case VT_CY :
//    if ( m_vtData.vt == VT_NULL )
//      (*(COleCurrency*)*ppValue).m_cur.int64 = 0L;
//    else
      (*(COleCurrency*)*ppValue) = m_vtData.cyVal;
    break;

  case VT_DATE :
//    if ( m_vtData.vt == VT_NULL )
//      (*(COleDateTime*)*ppValue) = COleDateTime();
//    else
      ((COleDateTime*)*ppValue)->operator =(m_vtData);
    break;

  case VT_DECIMAL :
//    if ( m_vtData.vt == VT_NULL )
//      (*(double*)*ppValue) = 0L;
 //   else
      hr = VarR8FromDec(&m_vtData.decVal, (double*)*ppValue);
    break;

  case VT_UI1 :
    (*(BYTE*)*ppValue) = m_vtData.bVal;
    break;

  case VT_ARRAY | VT_UI1 :
    //Place holder for Image data type to avoid default action
    break;

  default :
    m_vtData.Clear();
    break;
  }

  return ( hr );
}


HRESULT CAxRecordset::_setFldValue(ADOField* pFld, unsigned short varType, void** ppValue)
{
  HRESULT hr = S_OK;

  m_vtData.vt = varType;

  switch ( varType )
  {
  case VT_I2 :
    m_vtData.iVal = *(short*)*ppValue;
    break;

  case VT_I4 :
    m_vtData.lVal = *(long*)*ppValue;
    break;

//VT_I8 not supported under VS6
  case VT_I8 :
#if _MSC_VER > 1200
    m_vtData.llVal = *(LONGLONG*)*ppValue;
#else
    m_vtData.cyVal.int64 = (*(LONGLONG*)*ppValue);
#endif
    break;

  case VT_R4 :
    m_vtData.fltVal = *(float*)*ppValue;
    break;

  case VT_R8 :
    m_vtData.dblVal = *(double*)*ppValue;
    break;

  case VT_BOOL :
    m_vtData.boolVal = (*(bool*)*ppValue) ? VARIANT_TRUE : VARIANT_FALSE;
    break;

  case VT_VARIANT :
    m_vtData = *(VARIANT*)*ppValue;
    break;

  case VT_BSTR :
    m_vtData.bstrVal = ((CString*)*ppValue)->AllocSysString();
    break;

  case VT_CY :
    m_vtData.cyVal = *(CURRENCY*)*ppValue;
    break;

  case VT_DATE :
    hr = VarDateFromR8((*(DATE*)*ppValue), &m_vtData.date);
    break;

  case VT_DECIMAL :
    hr = VarDecFromR8((*(double*)*ppValue), &m_vtData.decVal);
    break;

  case VT_UI1 :
    m_vtData.bVal = *(BYTE*)*ppValue;
    break;

  case VT_ARRAY | VT_UI1 :
    //Place holder for Image data type to avoid default action
    break;

  default :
    m_vtData.Clear();
    break;
  }

  if ( SUCCEEDED(hr) )
      hr = pFld->put_Value(m_vtData);

  return ( hr );
}

HRESULT CAxRecordset::_setGetFieldValue(bool bSave, LPCTSTR lpszColumn, 
                                        unsigned short varType, void* pvValue)
{
  ADOField* pADOFld = NULL;
  m_hr = S_OK;

  //If we get an error here, assume the query
  //that resulted in the returned recordset
  //simply did not specify the field in question
  //rather than a bad field definition. The
  //ERROR_INVALID_ACCESS result is returned which
  //is not considered a fatal error.
  m_hr = _getADOField(lpszColumn, &pADOFld);
  if FAILED(m_hr)
    return ( (HRESULT)ERROR_INVALID_ACCESS );

  m_hr = _isUpdatable(pADOFld);
  if FAILED(m_hr)
    return ( m_hr );

  if ( bSave && (m_hr != ERROR_ACCESS_DENIED) )
    m_hr = _setFldValue(pADOFld, varType, &pvValue);
  else
    m_hr = _getFldValue(pADOFld, varType, &pvValue);

  return ( m_hr );
}


//Max size is 8k
void CAxRecordset::FX_Binary(bool bSave, LPCTSTR lpszColumn, BYTE** ppValue)
{
  if ( bSave && *ppValue != NULL )
  { 
    BINDATAINFOHEADER binHeader;
    memcpy((void*)&binHeader, (const void*)*ppValue, sizeof(BINDATAINFOHEADER));
    if ( binHeader.imgSize > 8192 )
		  ThrowAxException(AXLIB_ERROR_BUF_SIZE);
  }
  
  FX_Image(bSave, lpszColumn, ppValue);
}


//Max size is 2^31 - 1 (2,147,483,647) bytes
void CAxRecordset::FX_Image(bool bSave, LPCTSTR lpszColumn, BYTE** ppValue)
{
	HRESULT hr = S_OK;
	BYTE HUGEP *pData = NULL;
  m_vtData.Clear();

  if ( bSave )
  {
    if ( *ppValue == NULL )
      return;

    //Read the header information
 	  BINDATAINFOHEADER binHeader;
    BYTE* pBuf = *ppValue;

	  memcpy((void*)&binHeader, (const void*)pBuf, sizeof(BINDATAINFOHEADER));
    long lBufSize = sizeof(BINDATAINFOHEADER) + binHeader.imgSize;
   
		SAFEARRAYBOUND rgsabound[1];
		rgsabound[0].lLbound = 0;
		rgsabound[0].cElements = lBufSize;

    m_vtData.vt = VT_ARRAY | VT_UI1;
    m_vtData.parray = SafeArrayCreate(VT_UI1, 1, rgsabound);

		if ( m_vtData.parray != NULL )
		{
			hr = SafeArrayAccessData(m_vtData.parray, (void HUGEP* FAR*)&pData);
			if ( SUCCEEDED(hr) )
			{
				memcpy((void*)pData, (const void*)pBuf, lBufSize);
				hr = SafeArrayUnaccessData(m_vtData.parray);
  
        hr = _setGetFieldValue(bSave, lpszColumn, VT_ARRAY | VT_UI1, NULL);

        if ( FAILED(m_hr) )
          ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::FX_Image"), hr);

        //Clear the variant to free memory used by the parray member
        m_vtData.Clear();
			}
		}
  }
  else
  {
   if ( *ppValue != NULL )
    {
      delete [] *ppValue;
      *ppValue = NULL;
    }
    hr = _setGetFieldValue(bSave, lpszColumn, VT_ARRAY | VT_UI1, NULL);

    if ( FAILED(hr) )
      ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::FX_Image"), hr);

		if ( m_vtData.vt == VT_NULL )
			return;

    long lUBound;
		hr = SafeArrayGetUBound(m_vtData.parray, 1, &lUBound);
		if ( SUCCEEDED(hr) )
		{
			hr = SafeArrayAccessData(m_vtData.parray, (void HUGEP* FAR*)&pData);
			if ( SUCCEEDED(hr) )
			{
				long lByteCount = lUBound + 1;	//UBound is 0's based
				*ppValue = new BYTE[lByteCount];
				ZeroMemory((void*)*ppValue, lByteCount);

				memcpy((void*)*ppValue, (const void*)pData, lByteCount);

				SafeArrayUnaccessData(m_vtData.parray);
			}
		}
  }

}


//Max size is 8K
void CAxRecordset::FX_VarBinary(bool bSave, LPCTSTR lpszColumn, BYTE** ppValue)
{
  if ( bSave && *ppValue != NULL )
  { 
    BINDATAINFOHEADER binHeader;
    memcpy((void*)&binHeader, (const void*)*ppValue, sizeof(BINDATAINFOHEADER));
    if ( binHeader.imgSize > 8192 )
		  ThrowAxException(AXLIB_ERROR_BUF_SIZE);
  }
  
  FX_Image(bSave, lpszColumn, ppValue);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -