.h class CADOOperation { public: CADOOperation(void); ~CADOOperation(void); public://类型 static const DWORD ADO_TYPE_BITMAP_HANDLE;//位图句柄类型 static const DWORD ADO_TYPE_INT;//整型类型 static const DWORD ADO_TYPE_FLOAT;//浮点类型 static const DWORD ADO_TYPE_DATE;//日期类型 static const DWORD ADO_TYPE_BITMAP_FIEL;//位图文件类型 static const DWORD ADO_TYPE_STRING;//字符串类型 static const DWORD ADO_TYPE_TEXT;//文本类型 private: _ConnectionPtr m_pConnection;//连接指针 _RecordsetPtr m_pRecordset;//记录集指针 public: bool OpenRecordset(CString sql); void ShowError(_bstr_t error); bool OpenTable(CString name); void CloseRecorset(void); bool CloseTable(void); HRESULT AddNew(void); bool UpdateData(void); bool SetItemContent(CString field, DWORD type, const void* variable); bool ChangeTypeTo(_variant_t from, DWORD type, void* pTo, long add); private: HDC m_hDC; public: bool GetItemContent(CString field, DWORD type, void* variable); _variant_t GetSubItem(CString field); bool GetItemContent(DWORD field, DWORD type, void* variable); _variant_t GetSubItem(DWORD index); bool DeleteItemD(DWORD index); HRESULT MoveFirst(void); HRESULT MoveNext(void); bool MoveTo(DWORD index); private: DWORD m_CurrentRecord; public: bool IsLastRow(void); DWORD GetRecordCount(void); void SetClientDC(HDC hDc); }; .cpp #include "ADOOperation.h" //初始化静态对象 const DWORD CADOOperation::ADO_TYPE_STRING = 100; const DWORD CADOOperation::ADO_TYPE_BITMAP_FIEL = 101; const DWORD CADOOperation::ADO_TYPE_INT = 102; const DWORD CADOOperation::ADO_TYPE_FLOAT = 103; const DWORD CADOOperation::ADO_TYPE_DATE = 104; const DWORD CADOOperation::ADO_TYPE_BITMAP_HANDLE = 105; const DWORD CADOOperation::ADO_TYPE_TEXT = 106; CADOOperation::CADOOperation(void) : m_CurrentRecord(0) { try{ //创建connection连接对象 m_pConnection.CreateInstance(_uuidof(Connection)); //设置连接字符串 m_pConnection->Open(_bstr_t(Provider), "", "", adModeUnknown); } catch(_com_error e)//捕捉异常 { AfxMessageBox(e.Description(), MB_OK); exit(0); } m_pRecordset.CreateInstance(_uuidof(Recordset)); m_CurrentRecord=-1; m_hDC=NULL;//初始化当前的设备环境变量为NULL } CADOOperation::~CADOOperation(void) { m_pConnection->Close();//关闭连接 } bool CADOOperation::OpenRecordset(CString sql) { ASSERT(!sql.IsEmpty()); try { m_pRecordset->Open(_bstr_t(sql), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } void CADOOperation::ShowError(_bstr_t error) { ::MessageBox(NULL, error, _T("ADO错误"), MB_OK | MB_ICONWARNING); } bool CADOOperation::OpenTable(CString name) { ASSERT(!name.IsEmpty()); CString sql; sql.Format(_T("select * from %s") , name); try { m_pRecordset->Open(_bstr_t(sql), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } void CADOOperation::CloseRecorset(void) { try { if(adStateOpen == m_pRecordset->GetState()) m_pRecordset->Close(); } catch(_com_error e) { return ; } } bool CADOOperation::CloseTable(void) { try { if(adStateOpen == m_pRecordset->GetState()) m_pRecordset->Close(); } catch(_com_error e) { return false; } return true; } HRESULT CADOOperation::AddNew(void) { return m_pRecordset->AddNew(); } bool CADOOperation::UpdateData(void) { try { m_pRecordset->Update(); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } bool CADOOperation::SetItemContent(CString field, DWORD type, const void* variable) { ASSERT(!field.IsEmpty());//字段不能为空 ASSERT(variable != NULL);//指针不能为空 try { switch(type) { case ADO_TYPE_STRING://字符串类型 m_pRecordset->PutCollect(_bstr_t(field), _bstr_t(*(CString*)(variable)));//直接读取 break; case ADO_TYPE_BITMAP_FIEL://位图文件类型 { CString* lpStr = (CString*)variable;//得到位图名字字符串 VARIANT bitData = {0}; CFile file(*lpStr, CFile::modeRead);//位图文件 DWORD fileSize = file.GetLength() + 1;//得到文件长度 char* bitBuffer = new char[fileSize];//新建文件的缓冲区 file.Read(bitBuffer,fileSize); //file.ReadHuge(bitBuffer, fileSize);//读出文件的内容 file.Close();//关闭文件 bitData.vt = VT_ARRAY | VT_UI1;//设置数据类型为数组类型 SAFEARRAY* pSafeArray; SAFEARRAYBOUND arrayBound[1]; arrayBound[0].cElements = fileSize - 1;//设定数组的大小 arrayBound[0].lLbound = 0;//起始边界 pSafeArray = ::SafeArrayCreate(VT_UI1, 1, arrayBound);//得到数组指针 for(long i = 0; i <(long)fileSize-1; i++) ::SafeArrayPutElement(pSafeArray, &i, bitBuffer++);//为数组填充元素 bitData.parray = pSafeArray; //把数据写入数据库 m_pRecordset->GetFields()->GetItem(_bstr_t(field))->AppendChunk(bitData); } break; case ADO_TYPE_TEXT://文本类型 { CString* lpStr = (CString*)variable;//把指针转换为字符指针 VARIANT data; SAFEARRAY* pSafeArray; SAFEARRAYBOUND arrayBound; wchar_t *buf; data.vt = VT_ARRAY | VT_UI1;//设置类型为数组类型 arrayBound.cElements = lpStr->GetLength();//设置元素个数 arrayBound.lLbound = 0;//起始边界为0 pSafeArray = ::SafeArrayCreate(VT_UI1, 1, &arrayBound); buf = lpStr->GetBuffer(0); for(unsigned long i = 0; i < arrayBound.cElements; i++) ::SafeArrayPutElement(pSafeArray, (long*)&i, buf++); data.parray = pSafeArray;//填充元素 m_pRecordset->GetFields()->GetItem(_bstr_t(field))->AppendChunk(data);//写入数据库 } break; case ADO_TYPE_DATE://日期类型 { CString str; LPSYSTEMTIME lpSystemTime = (LPSYSTEMTIME)variable;//把指针类型转换为日期指针 str.Format(_T("%d-%d-%d"), lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay);//以字符串的形式存储日期 m_pRecordset->PutCollect(_bstr_t(field), _bstr_t(str));//保存数据 } break; case ADO_TYPE_INT://整数类型 { CString str; str.Format(_T("%d"), *(int*)variable); m_pRecordset->PutCollect(_bstr_t(field), _bstr_t(str)); } break; case ADO_TYPE_FLOAT://浮点数类型 { CString str; str.Format(_T("%.2f"), *(float*)variable);//以字符串的形式存储 m_pRecordset->PutCollect(_bstr_t(field), _bstr_t(str)); } break; default: return false; } } catch(_com_error e)//捕获可能的异常 { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } bool CADOOperation::ChangeTypeTo(_variant_t from, DWORD type, void* pTo, long add) { ASSERT(NULL != pTo);//要转换成的类型不能为空 switch(type) { case ADO_TYPE_DATE: { if(from.vt == VT_NULL) return FALSE; LPSYSTEMTIME sysTime = (LPSYSTEMTIME)pTo; char* temp=(char*)_bstr_t(from); // CString str = (char*)_bstr_t(from); CString m_strTime; m_strTime.Format(_T("%s"),temp); //CString d ,m,y; CString year,month,day; year=m_strTime.Left(4); m_strTime=m_strTime.Right(m_strTime.GetLength()-m_strTime.Find(_T("/"))-1); month=m_strTime.Left (m_strTime.Find (_T("/"))); day=m_strTime.Right(m_strTime.GetLength()-m_strTime.Find(_T("/"))-1); int y=_ttoi(year); int m=_ttoi(month); int d=_ttoi(day); /*n = str.Find(_T("-"), 0); y = str.Left(n); l = str.Find(_T("-"), n + 1); d = str.Right(str.GetLength() - l - 1); m = str.Mid(n + 1, l-n-1);*/ sysTime->wDay = d; sysTime->wMonth = m; sysTime->wYear =y; } break; case ADO_TYPE_FLOAT: if(from.vt == VT_NULL) { (*(double*)pTo) = 0; break; } (*(double*)pTo) = (double)from; break; case ADO_TYPE_BITMAP_HANDLE: { if(from.vt == VT_NULL) return FALSE; if(add > 0) { char *pBuffer; if((pBuffer = new char[add]) != NULL) { if(from.vt == (VT_ARRAY | VT_UI1)) { char *pBuf; ::SafeArrayAccessData(from.parray, (void**)&pBuf); ::memcpy(pBuffer, pBuf, add); ::SafeArrayUnaccessData(from.parray); char *pDib; LPVOID lpDibBits; BITMAPFILEHEADER &bmfHeader = *(BITMAPFILEHEADER*)pBuffer; DWORD bmfHeaderLen = sizeof(bmfHeader); if(bmfHeader.bfType != (*(DWORD*)"BM")) return TRUE; pDib = pBuffer + bmfHeaderLen; BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)pDib; BITMAPINFO &bmInfo = *(LPBITMAPINFO)pDib; lpDibBits = pBuffer + ((BITMAPFILEHEADER*)pBuffer)->bfOffBits; *(HBITMAP*)pTo = ::CreateDIBitmap(m_hDC, &bmiHeader, CBM_INIT, lpDibBits, &bmInfo, DIB_RGB_COLORS); } } } } break; case ADO_TYPE_TEXT: { CString *pStr = (CString* )pTo; *pStr = (char*)_bstr_t(from); } break; case ADO_TYPE_INT: if(from.vt == VT_NULL) { (*(long*)pTo) = 0; break; } (*(long*)pTo) = (long)from; break ; case ADO_TYPE_STRING: *(CString* )pTo = (char*)_bstr_t(from); break; default: return false; } return true; } bool CADOOperation::GetItemContent(CString field, DWORD type, void* variable) { ASSERT(!field.IsEmpty()); _variant_t variant; try { if(type != ADO_TYPE_BITMAP_HANDLE && type != ADO_TYPE_TEXT) { variant = GetSubItem(field); if (variant.vt==VT_NULL||variant.vt==VT_EMPTY) { variant=""; } ChangeTypeTo(variant, type, variable, 0); return TRUE; } if(type == ADO_TYPE_BITMAP_HANDLE || ADO_TYPE_TEXT == type) { long bits; bits = m_pRecordset->GetFields()->GetItem(_bstr_t(field))->ActualSize; if(bits <= 0) return TRUE; variant = m_pRecordset->GetFields()->GetItem(_bstr_t(field))->GetChunk(bits); ChangeTypeTo(variant, type, variable, bits); } } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } /* * 函数名称:获取子项目 * 函数功能:获取特定字段的子项目 * 参数列表:field:要执行的sql语句字段 * @ruturn :var 返回成功的项目 * 修改记录: 2010-5-26 Finger */ _variant_t CADOOperation::GetSubItem(CString field) { variant_t var; try{ var = m_pRecordset->GetCollect(_bstr_t(field)); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return var; } return var; } bool CADOOperation::GetItemContent(DWORD field, DWORD type, void* variable) { ASSERT(type != ADO_TYPE_BITMAP_HANDLE); _variant_t variant; bool ret = true; try{ variant = m_pRecordset->GetCollect(_variant_t((long)field)); ret = ChangeTypeTo(variant, type, variable, 0); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return ret; } _variant_t CADOOperation::GetSubItem(DWORD index) { _variant_t var; try{ var = m_pRecordset->GetCollect(_variant_t((long)index)); } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return var; } return var; } bool CADOOperation::DeleteItemD(DWORD index) { ASSERT(index >= 0); try { m_pRecordset->Move(index); m_pRecordset->Delete(adAffectCurrent); }catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } HRESULT CADOOperation::MoveFirst(void) { return m_pRecordset->MoveFirst(); } HRESULT CADOOperation::MoveNext(void) { return m_pRecordset->MoveNext(); } bool CADOOperation::MoveTo(DWORD index) { try { m_pRecordset->Move(index); m_CurrentRecord = index; } catch(_com_error e) { #ifdef _DEBUG ShowError(e.Description()); #endif return false; } return true; } bool CADOOperation::IsLastRow(void) { if(m_pRecordset->adoEOF) return true; return false; } DWORD CADOOperation::GetRecordCount(void) { DWORD count = 1; if(m_pRecordset->adoEOF) return 0; m_pRecordset->MoveFirst(); do { count++; m_pRecordset->MoveNext(); }while(!m_pRecordset->adoEOF); return count; } void CADOOperation::SetClientDC(HDC hDc) { m_hDC = hDc; }