程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> Ado實現C++對象的存取

Ado實現C++對象的存取

編輯:關於VC++

其實我最討厭寫東西了,最近忙死了,呵呵,前一段時間在做一個圖形程序時,需要把C++對象保存到數據庫裡,剛開始真讓我頭疼啊,琢磨了一個下午,終於給做出來了,廢話不說了,還是把自己的一些體會與各位同任一起分享!!!!

一、新建一個繼承於 CObject 的子類 CLine;

頭文件:Line.h class CLine : public CObject?
{
private :
  LOGPEN m_logPen; //畫筆
  COLORREF m_crBackColor;
    CArray<CPoint, CPoint &> m_PointArray; //標記類對應框

public:
  int GetSize();
  CPoint GetPoint(int pos);
  void DrawLine(CDC *pDC,CPoint pt1,CPoint pt2,CRect rc);
  void DrawBackGround(CDC *pDC,CRect rect);
  void DrawPoint(CDC *pDC, CRect rect);
  void SetWidth(int iWidth);
  COLORREF GetColor();
  void SetColor(COLORREF color);

  COLORREF GetBkColor();
  void SetBkColor(COLORREF color);

  void AddPoint(CPoint point);
  void Clear();
  CLine();
  virtual ~CLine();
  virtual void Serialize(CArchive &ar);
  CLine& operator=(CLine &src);
  DECLARE_SERIAL(CLine)??
};

實現文件:Line.cpp

//////////////////////////////////////////////////////////////////////
// Line.cpp: implementation of the CLine class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TestAdo.h"
#include "Line.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_SERIAL(CLine,CObject,1)
CLine::CLine()
{
   Clear();
}
CLine::~CLine()
{

}
//重寫 =
CLine& CLine::operator=(CLine &src)
{
   if(this!=&src)
   {
     m_logPen = src.m_logPen;
     m_crBackColor = src.m_crBackColor;
   }
   return *this;?
}
//串行化操作
void CLine::Serialize(CArchive &ar)
{
   if (ar.IsStoring())
   {
     ar << DWORD(m_crBackColor);
     ar.Write(&m_logPen, sizeof(LOGPEN));
   }
   else
   {
     DWORD dw;
     ar >> dw; m_crBackColor = COLORREF(dw);
     ar.Read(&m_logPen, sizeof(LOGPEN));
   }
   m_PointArray.Serialize(ar);
}
void CLine::Clear()
{
   m_crBackColor = RGB(255,255,255);
   m_logPen.lopnStyle = PS_SOLID;
   m_logPen.lopnWidth.x = 1;
   m_logPen.lopnWidth.y = 1;
   m_logPen.lopnColor = RGB(0, 0, 0);
   m_PointArray.RemoveAll();
}
void CLine::AddPoint(CPoint point)
{
   m_PointArray.Add(point);
}
void CLine::SetColor(COLORREF color)
{
   m_logPen.lopnColor = color;
}
COLORREF CLine::GetColor()
{
   return m_logPen.lopnColor;
}
void CLine::SetBkColor(COLORREF color)
{
   m_crBackColor = color;
}
COLORREF CLine::GetBkColor()
{
   return m_crBackColor;
}
void CLine::SetWidth(int iWidth)
{
   m_logPen.lopnWidth.x = iWidth;
   m_logPen.lopnWidth.y = iWidth;

}
//繪線條
void CLine::DrawPoint(CDC *pDC, CRect rect)
{
   int len = m_PointArray.GetSize();
   if (len <=0) return;
   CPen pen;
   pen.CreatePenIndirect(&m_logPen);
   CPen *pOldPen = pDC->SelectObject(&pen);
   CPoint pt = m_PointArray.GetAt(0);
   pDC->MoveTo(pt);
   for (int i=1; i< len; i++)
   {
     pt = m_PointArray.GetAt(i);
     pDC->LineTo(pt);
   }
   pDC->SelectObject(pOldPen);
   pOldPen = NULL;
   pen.DeleteObject();
}
void CLine::DrawBackGround(CDC *pDC, CRect rect)
{
   CBrush brushCtl;
   brushCtl.CreateSolidBrush(GetBkColor());
   pDC->Rectangle(rect);
   pDC->FillRect(rect,&brushCtl) ;
   brushCtl.DeleteObject();
}
void CLine::DrawLine(CDC *pDC,CPoint pt1, CPoint pt2, CRect rc)
{
   CPen pen;
   pen.CreatePenIndirect(&m_logPen);
   CPen *pOldPen = pDC->SelectObject(&pen);
   pDC->MoveTo(pt1);
   pDC->LineTo(pt2);
   pDC->SelectObject(pOldPen);
   pOldPen = NULL;
   pen.DeleteObject();
}
CPoint CLine::GetPoint(int pos)
{
   if (pos>=0 && pos<m_PointArray.GetSize())?
   {
     return m_PointArray.GetAt(pos);
   }
   return CPoint(0,0);
}
int CLine::GetSize()
{
   return m_PointArray.GetSize();
}

二、用Ado接口打開數據庫

BOOL CTestAdoDlg::OpenDb(CString filename)
{
  HRESULT hr=S_OK;
  hr=m_pCon.CreateInstance("ADODB.Connection");
  if (hr!=S_OK)
  {
    return FALSE;
  }
  try
  {
    _bstr_t sCon;
    sCon=_bstr_t(filename); //路徑名
    sCon="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+sCon;
    hr=m_pCon->Open(sCon,"","",adModeUnknown);
    if (hr!=S_OK)
    {
      return FALSE;
    }
    ///////////////////////
    hr=m_pSet.CreateInstance("ADODB.Recordset");
    if (hr!=S_OK)
    {
      return FALSE;
    }
    m_pSet->CursorLocation=adUseClient;
    hr=m_pSet->Open("SELECT * FROM object_table",_variant_t((IDispatch*)m_pCon,TRUE),
      adOpenStatic,adLockOptimistic,adCmdText);
    if (hr!=S_OK)
    {
      return FALSE;
    }
    return TRUE;
    ///////////////////////
  }
  catch(_com_error &e)
  {
    CString errorMessage;
    errorMessage.Format("連接數據庫失敗!錯誤信息:%s",e.ErrorMessage());
    return FALSE;
  }
  return FALSE;
}
(注意:在StdAfx.h中要加入:#import "C:\Program Files\Common Files\SYSTEM\ADO\msado15.dll" no_namespace rename("EOF","adoEOF")

來引入ado庫,還有在 BOOL CTestAdoApp::InitInstance() 加入 AfxOleInit();///初始化COM庫)

三、CLine對象的保存

void CTestAdoDlg::OnButtonSave()
{
  //m_List
  if (!m_bState) return;
  UpdateData();
  try
  {
    m_pSet->AddNew();
    m_pSet->PutCollect("name", _variant_t(m_sName));

    //保存圖形對象
    CMemFile memFile;
    CArchive ar(&memFile, CArchive::store);
    m_Line.Serialize(ar);
    ar.Close();

    DWORD dwSize = memFile.GetLength();
    LPBYTE lpInfo = memFile.Detach();

    VARIANT varBLOB;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];

    rgsabound[0].lLbound = 0;
    rgsabound[0].cElements = dwSize;

    psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
    for (long i = 0; i < (long)dwSize; i++)
    {
      SafeArrayPutElement (psa, &i, lpInfo++);
    }
    varBLOB.vt = VT_ARRAY | VT_UI1;
    varBLOB.parray = psa;
    m_pSet->GetFields()->GetItem("object")->AppendChunk(varBLOB);
    m_pSet->Update();
    m_List.AddString(m_sName);
  }
  catch(_com_error &e)
  {
    CString str=(char *)e.Description();
    MessageBox(str+"\r保存數據庫出問題!","提示",MB_OK|MB_ICONWARNING);
    return ;
  }

}

四、CLine對象的讀取

void CTestAdoDlg::OnSelchangeListData()
{
   int iPos = m_List.GetCurSel();
   if (iPos<0) return ;
   m_pSet->MoveFirst();

   int i=0;
   while (i< iPos)
   {
     m_pSet->MoveNext();
     i++;
   }
   long lDataSize = m_pSet->GetFields()->GetItem(_variant_t("object"))->ActualSize;
   if(lDataSize <= 0) return;

   _variant_t varBLOB;
   VariantInit (&varBLOB);

   varBLOB = m_pSet->GetFields()->GetItem(_variant_t("object"))->GetChunk(lDataSize);
   if(varBLOB.vt == (VT_ARRAY | VT_UI1))
   {
     BYTE *pBuf = new BYTE[lDataSize + 1];
     if(pBuf)
     {
       SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
       SafeArrayUnaccessData (varBLOB.parray);

       CMemFile memfile;
       memfile.Attach(pBuf,lDataSize);
       memfile.SeekToBegin();
       CArchive ar(&memfile, CArchive::load);

       m_Line.Serialize(ar);
       ar.Close();
       memfile.Detach();
       CRect rc = GetRect(IDC_STATIC_RECT);
       InvalidateRect(rc);
     }
   }
   VariantClear (&varBLOB);
}

五、結束語

以上充分利用了串行化來實現c++對象保存到數據庫,對以上方法稍做擴展對圖象的保存到數據庫,甚至多個圖象文件保存到數據庫和文件。

(很抱歉:我實在不想寫文字說明了,如果有什麼問題不清楚,跟我聯系好了!!哎)

QQ:36201365

e-mail:[email protected]

本文配套源碼

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved