通过COM使用ADO

在Visual C++或C++ Builder中,我们可以通过访问ADO的COM对象来将对ADO的操作封装成一个类。首先,我们需要对MSADO15.DLL进行导入,让它生成类型库。在C++ Builder中,用TLIBIMP.EXE来生成ADODB_TLB.h,ADODB_TLB.cpp等文件,然后我们通过阅读类型库中的信息,从而可以写成这个类:
.h File
#ifndef ADOH
#define ADOH
#include "ADODB_TLB.h"
#include "utilcls.h"
#include <dstring.h>
class CValue
{
public:
     CValue();
     ~CValue();
     Variant m_value;
     BOOL AsBool();
     String AsString();
     int AsInt();
     float AsFloat();
     TDateTime AsDate();
};

class ADOConnection
{
public:
 ADOConnection();
 virtual ~ADOConnection();
public:
 _ConnectionPtr m_pConnection;
 BOOL  m_bConnectionOpen;
   BOOL  m_bInstance;
   int m_nOpenMode;
 BOOL  Open(BSTR dsn,BSTR uid,BSTR pwd);
};
class ADOrecordset
{
public:
 ADOrecordset();
 virtual ~ADOrecordset();
public:
   _ConnectionPtr m_pConnection;
 _RecordsetPtr  m_recordset;
 BOOL    m_bOpen;
 BOOL    SetConnect(_ConnectionPtr _pConnection);
 BOOL Open(WideString sql);
 HRESULT GetFieldValue(Variant idx,Variant * newVal);
 CValue GetFieldValue(String sName);
 CValue GetFieldValue(long index);
 HRESULT GetFieldCount(long &Count);//added by chenbin
 HRESULT GetFields(long index,String& sFieldList);//added by chenbin
 HRESULT GetFieldType(FieldPtr pField,String& strMsg,long& nResult);//added by chenbin
 HRESULT GetFieldType(String FieldName,String& strMsg,long& nResult);//added by chenbin
 BOOL    get_BOF();
 BOOL    get_EOF();
 HRESULT Prev();
 HRESULT Last();
 HRESULT Next();
 HRESULT First();
 HRESULT CloseRecordset(void);
};
#endif


.cpp File
#ifdef __BORLANDC__
#include <vcl.h>
#pragma hdrstop
#endif
#include "ADO.h"
file://----------Class CValue-------------------
CValue::CValue()
{

   file://If necessary,you may add codes here......
}
CValue::~CValue()
{
   file://If necessary,you may add codes here.........
}
BOOL CValue::AsBool()
{
   if(m_value.IsEmpty()) return false;
   else return m_value.AsType(varBoolean);
}
String CValue::AsString()
{
   if(m_value.IsEmpty()) return "";
   else return m_value.AsType(varString);
}
int CValue::AsInt()
{
   int m_int;
   if(m_value.IsEmpty()) return 0;
   else
   {
      switch(m_value.Type())
      {
         case varSmallint:
            m_int=m_value.AsType(varSmallint);
            break;
         case varInteger:
            m_int=m_value.AsType(varInteger);
            break;
         default:
            m_int=0;
      }
   }
   return m_int;
}
float CValue::AsFloat()
{
   float m_float;
   if(m_value.IsEmpty()) return 0;
   else
   {
      switch(m_value.Type())
      {
         case varSingle:
            m_float=m_value.AsType(varSingle);
            break;
         case varDouble:
            m_float=m_value.AsType(varDouble);
            break;
         default:
            m_float=0;
            break;
      }
   }
   return m_float;
}
TDateTime CValue::AsDate()
{
   file://1970-01-01 12:00:00 is invalid datetime
   TDateTime dt=StrToDateTime("1970-01-01 12:00:00");
   if(m_value.IsEmpty()) return dt;
   else return m_value.AsType(varDate);
}

file://----------------Class ADOConnection------------
ADOConnection::ADOConnection()
{
   m_bConnectionOpen= FALSE;
   m_bInstance=FALSE;
 file://If necessary,you may add codes here....
}
ADOConnection::~ADOConnection()
{
   m_bInstance=FALSE;
   m_bConnectionOpen=FALSE;
   file://If necessary,you may add codes here....
}
BOOL ADOConnection::Open(wchar_t* dsn,wchar_t* uid,wchar_t* pwd)
{
   HRESULT hr;
   if(!m_bInstance)
   {
      try
      {
         hr=m_pConnection.CreateInstance(__uuidof(Connection));
      }
      catch(Exception &e)
      {
         ::MessageBox(::GetActiveWindow(),e.Message.c_str(),"Error",MB_OK+MB_ICONERROR);
         return FALSE;
      }
      m_bInstance=true;
   }
   if(m_bConnectionOpen) return TRUE;
   try
   {
      hr=m_pConnection->Open(dsn,uid,pwd,adModeUnknown);
      m_nOpenMode=2;
   }
   catch(Exception &e)
   {
      ::MessageBox(::GetActiveWindow(),e.Message.c_str(),"Error",MB_OK+MB_ICONERROR);
      return FALSE;
   }
   m_bConnectionOpen=TRUE;
   hr=S_OK;
   return TRUE;
}
file://-------Class ADORecordset------------
ADOrecordset::ADOrecordset()
{
}
ADOrecordset::~ADOrecordset()
{
}
BOOL ADOrecordset::SetConnect(_ConnectionPtr _pConnection)
{
   if(_pConnection)
   {
      HRESULT hr=m_recordset.CreateInstance(__uuidof(Recordset));
      m_pConnection=_pConnection;
      if(SUCCEEDED(hr)==S_OK) return TRUE;
      else return FALSE;
   }
   else return FALSE;
}
BOOL ADOrecordset::Open(WideString sql)
{
   try
   {
      _CommandPtr m_Cmd("ADODB.Command");
      m_Cmd->_set_ActiveConnection(m_pConnection);
      m_Cmd->set_CommandText(sql);
      m_Cmd->set_CommandType(adCmdText);
      m_recordset=m_Cmd->Execute(NULL,NULL,adCmdText);
      m_bOpen=true;
   }
   catch(Exception &e)
   {
      m_bOpen=FALSE;
      return FALSE;
   }
   return TRUE;
}
HRESULT ADOrecordset::GetFieldValue(Variant idx,Variant * newVal)
{
   FieldsPtr *Fields=0;
   FieldPtr *Field=0;
   HRESULT hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Item(idx,Field);
      if(hr==S_OK)
      {
         hr=(*Field)->get_Value(*newVal);
      }
   }
   return hr;

}
CValue ADOrecordset::GetFieldValue(String sName)//Get Field's value according to the field's name
{
   FieldsPtr *Fields=0;
   FieldPtr *Field=0;
   CValue v;
   Variant idx=sName;
   if(m_recordset->get_Fields(Fields)==S_OK)
   {
      if((*Fields)->get_Item(idx,Field)==S_OK)
      {
         v.m_value=(*Field)->get_Value();
      }
   }
   return v;
}
CValue ADOrecordset::GetFieldValue(long index)
{
   FieldsPtr* Fields=0;
   FieldPtr* Field=0;
   CValue v;
   if(m_recordset->get_Fields(Fields)==S_OK)
   {
      if((*Fields)->get_Item(index,Field)==S_OK)
      {
         v.m_value=(*Field)->get_Value();
      }
   }
   return v;
}
HRESULT ADOrecordset::GetFieldCount(long &Count)
{
   FieldsPtr* Fields;
   HRESULT hr;
   hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Count(&Count);
   }
   return hr;
}
HRESULT ADOrecordset::GetFields(long index,String& sFieldList)
{
   FieldsPtr* Fields;
   FieldPtr* Field;
   HRESULT hr;
   WideString FieldName;
   long rec=0;
   hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Count(&rec);
      if(hr==S_OK)
      {
         for(int i=0;i<hr;i++)
         {
            hr=(*Fields)->get_Item(i,Field);
            if(hr==S_OK)
            {
               hr=(*Field)->get_Name(&FieldName);
               if(hr==S_OK)
               {
                  sFieldList+=(String)FieldName;
               }
            }
         }
      }
   }
   return hr;
}
HRESULT GetFieldType(FieldPtr pField,String& strMsg,long& nResult)
{
   file://Nowadays I don't use the function,which will be used according to needs in the future
   return S_OK;
}
HRESULT GetFieldType(String FieldName,String& strMsg,long& nResult)
{
   file://Nowadays I don't use the function,which will be used according to needs in the future
   return S_OK;
}
BOOL    ADOrecordset::get_BOF()
{
   BOOL bFlag=m_recordset->get_BOF();
   return bFlag;
}
BOOL    ADOrecordset::get_EOF()
{
   BOOL bFlag=m_recordset->get_EOF();
   return bFlag;
}
HRESULT ADOrecordset::Prev()
{
   HRESULT hr=m_recordset->MovePrevious();
   return hr;
}
HRESULT ADOrecordset::Last()
{
   HRESULT hr=m_recordset->MoveLast();
   return hr;
}
HRESULT ADOrecordset::Next()
{
   HRESULT hr=m_recordset->MoveNext();
   return hr;
}
HRESULT ADOrecordset::First()
{
   HRESULT hr=m_recordset->MoveFirst();
   return hr;
}
HRESULT ADOrecordset::CloseRecordset(void)
{
   HRESULT hr=m_recordset->Close();
   return hr;
}
写完这个类之后,以后在程序中就可以直接使用这个类来对ADO进行访问,写一个简单的测试代码:
假定我已在ODBC中新建一数据源:DSN=Test,Username=chenbin,Password=caiyao,那么如果想用ADO对该数据源进行访问的话,就可以用下面的代码:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ADOConnection m_Connection;
   ADOrecordset rst;
   if(m_Connection.Open(L"Test",L"chenbin",L"caiyao"))
   {
      if(rst.SetConnect(m_Connection.m_pConnection))
      {
         if(rst.Open("select * from family"))
         {
            if(rst.First()==S_OK)
            {
               while(!rst.get_EOF())
               {
                  Memo1->Lines->Add(rst.GetFieldValue("name").AsString());
                  rst.Next();
               }
            }
         }
      }
   }
}

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值