游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1104|回复: 1

Ado 实现C++对象的存取wxh zt

[复制链接]

66

主题

108

帖子

112

积分

注册会员

Rank: 2

积分
112
发表于 2005-5-18 22:49:00 | 显示全部楼层 |阅读模式
  其实我最讨厌写东西了,最近忙死了,呵呵,前一段时间在做一个图形程序时,需要把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:perator=(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:rawPoint(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=&quotrovider=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++对象保存到数据库,对以上方法稍做扩展对图象的保存到数据库,甚至多个图象文件保存到数据库和文件。

248

主题

2674

帖子

2702

积分

金牌会员

Rank: 6Rank: 6

积分
2702
QQ
发表于 2005-5-19 19:27:00 | 显示全部楼层

Re:Ado 实现C++对象的存取wxh zt

有没有办法,将整个对象保存进去,包括数据和代码,而不只是数据呢?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-25 16:49

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表