与C++中ADO数据库编程一样,WinCE中ADO数据库操作也需要_Connection和_Recordset指针,在此我们将其封装以求更方便,注:WinCE系统必须支持数据库的ADO操作。具体代码如下所示:
//VOConnection.h
#if !defined(AFX_VOCONNECTION_H__EE2E886A_8A8A_4CC8_9A48_28681F64544B__INCLUDED_)
#define AFX_VOCONNECTION_H__EE2E886A_8A8A_4CC8_9A48_28681F64544B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <COMDEF.H>
#include <ADOCE30.H>
#include "VOString.h"
class CVOConnection
{
public:
CVOConnection(LPCTSTR pcszProvider = NULL);
virtual ~CVOConnection();
BOOL Execute(LPCTSTR pcszSQL);
BOOL Initialize();
LPCTSTR GetProvider() { return m_strProvider; }
operator _Connection*() { return m_Conn; }
void SetConnectDB(LPCTSTR lpszDBName);
void ClearConnect();
protected:
CVOString m_strProvider;
static TCHAR* g_ProgID;
static CLSID g_ClsID;
static BOOL g_Init;
_Connection* m_Conn;
};
#endif // !defined(AFX_VOCONNECTION_H__EE2E886A_8A8A_4CC8_9A48_28681F64544B__INCLUDED_)
//VOConnection.cpp
#include "stdafx.h"
#include <COMDEF.H>
#include <ADOCE30.H>
#include "VOConnection.h"
#include "VORecordset.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const IID IID__Connection = { 0x113033de, 0xf682, 0x11d2, { 0xbb, 0x62, 0x00, 0xc0, 0x4f, 0x68, 0x0a, 0xcc}};
void __stdcall _com_issue_error(HRESULT m_hr)
{
TCHAR pcszError[1024];
_stprintf(pcszError, TEXT("_com_issue_error(%ld)\n"), m_hr);
OutputDebugString(pcszError);
}
BOOL CVOConnection::g_Init = FALSE;
CLSID CVOConnection::g_ClsID;
TCHAR* CVOConnection::g_ProgID = TEXT("ADOCE.Connection.3.0");
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern CVOConnection m_Conn;
CVOConnection::CVOConnection(LPCTSTR pcszProvider) : m_Conn(NULL)
{
if(!g_Init)
Initialize();
HRESULT hr;
if(pcszProvider == NULL)
{
// pcszProvider = TEXT("cedb");
hr = CoCreateInstance(g_ClsID, NULL, CLSCTX_INPROC_SERVER, IID__Connection, (LPVOID*) &m_Conn);
// hr = m_Conn->put_Provider((LPTSTR)pcszProvider);
hr = m_Conn->Open(TEXT("Disk\\tiger.mdb"),TEXT(""),TEXT(""),adOpenUnspecified);
}
else
{
m_strProvider = pcszProvider;
m_Conn = NULL;
}
}
CVOConnection::~CVOConnection()
{
if(m_Conn)
{
m_Conn->Close();
m_Conn->Release();
}
}
BOOL CVOConnection::Initialize()
{
if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
return FALSE;
HRESULT hr;
hr = CLSIDFromProgID(g_ProgID, &g_ClsID);
if(FAILED(hr))
return FALSE;
return TRUE;
}
BOOL CVOConnection::Execute(LPCTSTR pcszSQL)
{
CVORecordset rs(*this);
return rs.Open(pcszSQL, adOpenForwardOnly, adLockPessimistic);
}
void CVOConnection::SetConnectDB(LPCTSTR lpszDBName)
{
if( m_Conn )
{
m_Conn->Close();
m_Conn->put_Provider((LPTSTR)(TEXT("cedb")));
m_Conn->Open((LPTSTR)lpszDBName,TEXT(""),TEXT(""),adOpenUnspecified);
m_strProvider = lpszDBName;
}
}
void CVOConnection::ClearConnect()
{
if( m_Conn )
{
m_Conn->Close();
m_Conn->put_Provider((LPTSTR)(TEXT("cedb")));
m_Conn->Open(TEXT(""),TEXT(""),TEXT(""),adOpenUnspecified);
m_strProvider = TEXT("");
}
}
//VORecordset.h
#if !defined(AFX_VORECORDSET_H__B81BD14E_98F0_42A7_A64F_3FA21F5A3E5D__INCLUDED_)
#define AFX_VORECORDSET_H__B81BD14E_98F0_42A7_A64F_3FA21F5A3E5D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <COMDEF.H>
#include <ADOCE30.H>
#include "VOConnection.h"
class CVORecordset
{
public:
CVORecordset(CVOConnection& rConn);
virtual ~CVORecordset();
public:
LPCTSTR GetFieldValueString(int iField);
VARIANT GetFieldValue(int iField);
LPCTSTR GetFieldName(int iField);
Field* GetField(int iField);
long GetFieldCount() { return m_FldCnt; }
BOOL MoveNext();
BOOL MoveFirst();
BOOL IsEOF();
BOOL IsBOF();
BOOL Close();
// BOOL Open(LPCTSTR);
BOOL Open(LPCTSTR pcszSource, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType);
BOOL Initialize();
BOOL IsOpen() { return m_fIsOpen; }
operator _Recordset*() { return m_rs; }
protected:
BOOL m_fIsOpen;
CVOConnection& m_rConn;
_Recordset* m_rs;
Fields* m_Fields;
Field* m_Field;
long m_FldCnt;
static TCHAR* g_ProgID;
static CLSID g_ClsID;
static BOOL g_Init;
};
#endif // !defined(AFX_VORECORDSET_H__B81BD14E_98F0_42A7_A64F_3FA21F5A3E5D__INCLUDED_)
//VORecordset.cpp
#include "stdafx.h"
#include "VORecordset.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const IID IID__Recordset = { 0x113033f6, 0xf682, 0x11d2, { 0xbb, 0x62, 0x00, 0xc0, 0x4f, 0x68, 0x0a, 0xcc}};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
BOOL CVORecordset::g_Init = FALSE;
CLSID CVORecordset::g_ClsID;
TCHAR* CVORecordset::g_ProgID = TEXT("ADOCE.Recordset.3.0");
CVORecordset::CVORecordset(CVOConnection& rConn) : m_rConn(rConn), m_rs(NULL)
{
if(!g_Init)
Initialize();
HRESULT hr;
hr = CoCreateInstance(g_ClsID, NULL, CLSCTX_INPROC_SERVER, IID__Recordset, (LPVOID*)&m_rs);
VARIANT varConn;
varConn.pdispVal = (_Connection*)m_rConn;
varConn.vt = VT_DISPATCH;
hr = m_rs->put_ActiveConnection(varConn);
}
CVORecordset::~CVORecordset()
{
Close();
if(m_rs)
m_rs->Release();
}
BOOL CVORecordset::Initialize()
{
HRESULT hr;
hr = CLSIDFromProgID( g_ProgID, &g_ClsID);
return(!FAILED(hr));
}
BOOL CVORecordset::Open(LPCTSTR pcszSource, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType)
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::Open() RecordSet COM Object not initialized\n"));
return FALSE;
}
HRESULT hr;
m_rs->Close();
hr = m_rs->Open(_variant_t(pcszSource), _variant_t( TEXT("Disk\\tiger.mdb") ), CursorType, LockType, adCmdUnknown);
m_fIsOpen = (!FAILED(hr));
m_rs->get_Fields(&m_Fields);
m_Fields->get_Count(&m_FldCnt);
return m_fIsOpen;
}
BOOL CVORecordset::Close()
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::Close() RecordSet COM Object not initialized\n"));
return FALSE;
}
m_rs->Close();
m_fIsOpen = FALSE;
return TRUE;
}
BOOL CVORecordset::IsBOF()
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::BOF() RecordSet COM Object not initialized\n"));
return FALSE;
}
VARIANT_BOOL fValue;
HRESULT hr = m_rs->get_BOF(&fValue);
return (fValue == VARIANT_TRUE);
}
BOOL CVORecordset::IsEOF()
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::EOF() RecordSet COM Object not initialized\n"));
return FALSE;
}
VARIANT_BOOL fValue;
HRESULT hr = m_rs->get_EOF(&fValue);
return (fValue == VARIANT_TRUE);
}
BOOL CVORecordset::MoveFirst()
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::MoveFirst() RecordSet COM Object not initialized\n"));
return FALSE;
}
HRESULT hr = m_rs->MoveFirst();
return (!FAILED(hr));
}
BOOL CVORecordset::MoveNext()
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::MoveNext() RecordSet COM Object not initialized\n"));
return FALSE;
}
HRESULT hr = m_rs->MoveNext();
return (!FAILED(hr));
}
Field* CVORecordset::GetField(int iField)
{
if(!m_rs)
{
TRACE(TEXT("CVORecordset::GetField() RecordSet COM Object not initialized\n"));
return NULL;
}
HRESULT hr = m_Fields->get_Item(_variant_t((long)iField), &m_Field);
if(FAILED(hr))
return NULL;
return m_Field;
}
LPCTSTR CVORecordset::GetFieldName(int iField)
{
Field* pField = GetField(iField);
if(!pField)
{
TRACE(TEXT("CVORecordset::GetFieldName() Invalid Field Index\n"));
return NULL;
}
BSTR strFieldName;
pField->get_Name(&strFieldName);
return strFieldName;
}
VARIANT CVORecordset::GetFieldValue(int iField)
{
VARIANT value;
HRESULT hr;
VariantInit(&value);
Field* pField = GetField(iField);
if(!pField)
{
TRACE(TEXT("CVORecordset::GetFieldValue() Invalid Field Index\n"));
return _variant_t((long)0);
}
pField = GetField(iField);
hr = pField->get_Value(&value);
return value;
}
LPCTSTR CVORecordset::GetFieldValueString(int iField)
{
VARIANT value = GetFieldValue(iField);
VARIANT valueString;
VariantInit(&valueString);
if(value.vt == VT_BSTR)
valueString = value;
else
VariantChangeType(&valueString, &value, 0, VT_BSTR);
return valueString.bstrVal;
}
//VOString.h
#if !defined(AFX_VOSTRING_H__91406803_1D87_4DA9_A5A0_499A88AC4E86__INCLUDED_)
#define AFX_VOSTRING_H__91406803_1D87_4DA9_A5A0_499A88AC4E86__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CVOString
{
public:
CVOString(const CVOString& rSrc);
CVOString(LPCTSTR pcszValue = TEXT(""));
virtual ~CVOString();
operator LPCTSTR() { return (LPCTSTR)m_pBuffer; }
DWORD GetLength() { return m_dwLength; }
const CVOString& operator =(LPCTSTR pcszValue);
BOOL operator == (LPCTSTR pcszValue);
const CVOString& operator += (LPCTSTR pcszAppend);
protected:
BOOL SetMinBufferSize(DWORD dwChars);
DWORD m_dwLength;
DWORD m_dwBufferSize;
TCHAR* m_pBuffer;
};
#endif // !defined(AFX_VOSTRING_H__91406803_1D87_4DA9_A5A0_499A88AC4E86__INCLUDED_)
//VOString.cpp
//#include "stdafx.h"
#include "VOString.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVOString::CVOString(LPCTSTR pcszValue)
{
m_pBuffer = NULL;
m_dwBufferSize = 0;
*this = pcszValue;
}
// Copy Constructor
CVOString::CVOString(const CVOString &rSrc)
{
m_pBuffer = NULL;
m_dwBufferSize = 0;
*this = rSrc.m_pBuffer;
}
CVOString::~CVOString()
{
if(m_pBuffer)
delete m_pBuffer;
}
const CVOString& CVOString::operator = (LPCTSTR pcszValue)
{
m_dwLength = _tcslen(pcszValue);
SetMinBufferSize(m_dwLength);
_tcscpy(m_pBuffer, pcszValue);
return *this;
}
BOOL CVOString::operator == (LPCTSTR pcszValue)
{
return(_tcscmp(pcszValue, m_pBuffer) == 0);
}
const CVOString& CVOString::operator += (LPCTSTR pcszAppend)
{
SetMinBufferSize(GetLength() + _tcslen(pcszAppend));
_tcscat(m_pBuffer, pcszAppend);
return *this;
}
BOOL CVOString::SetMinBufferSize(DWORD dwChars)
{
if(m_dwBufferSize < dwChars + 1)
{
TCHAR* pNewBuffer;
DWORD dwNewBufferSize = dwChars + 256;
pNewBuffer = new TCHAR[dwNewBufferSize];
if(m_pBuffer)
{
memmove(pNewBuffer, m_pBuffer, m_dwBufferSize);
delete m_pBuffer;
}
m_pBuffer = pNewBuffer;
m_dwBufferSize = dwNewBufferSize;
}
return TRUE;
}