gusucode.com > ADO智能开发包C++源码程序 > ADO智能开发包/sfxdb_src_1.0.510.1/sfx/Source/db/src/ADODB.cpp

    #include "stdafx.h"
#include <tchar.h>
#include "adodb.h"
#include "FileDialogEx.h"
//#include "stl_type.h"
#include "Exception.h"
#include "..\sfxdb7.h"

//---------------------------------------------------------------------------------------

//CString GetError(_com_error &e)
//{	
//	CString MsgBug;
//	_bstr_t Source(e.Source());
//	_bstr_t Description(e.Description());
//	MsgBug.Format(_T("Ups!!! \nSource = %s\nDescription= %s\n"), (LPCSTR)Source, (LPCSTR)Description );
//	#ifdef _DEBUG
//		AfxMessageBox( MsgBug, MB_OK | MB_ICONERROR);
//	#endif	
//	return MsgBug;
//}

CString WINAPI VariantToStr(_variant_t &vart)
{
	CString m_strFieldValue;	

	switch (vart.vt)
	{
	case VT_BSTR://字符串
	case VT_LPSTR://字符串
	case VT_LPWSTR://字符串
		m_strFieldValue = (LPCTSTR)(_bstr_t)vart;
		break;
	case VT_I1:
	case VT_UI1:
		m_strFieldValue.Format(_T("%d"), vart.bVal);
		break;
	case VT_I2://短整型
		m_strFieldValue.Format(_T("%d"), vart.iVal);
		break;
	case VT_UI2://无符号短整型
		m_strFieldValue.Format(_T("%d"), vart.uiVal);
		break;
	case VT_INT://整型
		m_strFieldValue.Format(_T("%d"), vart.intVal);
		break;
	case VT_I4: //整型
		m_strFieldValue.Format(_T("%d"), vart.lVal);
		break;
	case VT_I8: //长整型
		m_strFieldValue.Format(_T("%d"), vart.lVal);
		break;
	case VT_UINT://无符号整型
		m_strFieldValue.Format(_T("%d"), vart.uintVal);
		break;
	case VT_UI4: //无符号整型
		m_strFieldValue.Format(_T("%d"), vart.ulVal);
		break;
	case VT_UI8: //无符号长整型
		m_strFieldValue.Format(_T("%d"), vart.ulVal);
		break;
	case VT_VOID:
		m_strFieldValue.Format(_T("%8x"), vart.byref);
		break;
	case VT_R4://浮点型
		m_strFieldValue.Format(_T("%.4f"), vart.fltVal);
		break;
	case VT_R8://双精度型
		m_strFieldValue.Format(_T("%.8f"), vart.dblVal);
		break;
	case VT_DECIMAL: //小数
		m_strFieldValue.Format(_T("%.8f"), (double)vart);
		break;
	case VT_CY:
		{
			COleCurrency m_OldCy;
			m_OldCy = vart.cyVal;
			m_strFieldValue = m_OldCy .Format();
		}
		break;
	case VT_BLOB:
	case VT_BLOB_OBJECT:
	case 0x2011:
		m_strFieldValue = _T("[BLOB]");
		break;
	case VT_BOOL://布尔型

		m_strFieldValue = vart.boolVal ? _T("TRUE") : _T("FALSE");
		break;
	case VT_DATE: //日期型
		{		
			COleDateTime m_da;

			m_da = COleDateTime(vart.date); 
			m_strFieldValue = m_da.Format(_T("%Y-%m-%d %H:%M:%S"));
		}
		break;
	case VT_NULL://NULL值
		m_strFieldValue = _T("");
		break;
	case VT_EMPTY://空
		m_strFieldValue = _T("");
		break;
	case VT_UNKNOWN://未知类型
	default:
		m_strFieldValue = _T("UN_KNOW");
		break;
	}
	return m_strFieldValue;
}

/////////////////////////////////////////////////////////////////////////
//	CDBBaseControl
//
VOID CDBBaseControl::ExitRecordset()
{
	//ASSERT(m_hWndCtrl);
	ASSERT(NULL != m_pRecordSet);

	if (NULL != m_pRecordSet)
	{
		m_pRecordSet->MoveView((CDBBaseControl*)this);
		m_pRecordSet = NULL;
	}
}


void CDBBaseControl::virDataChange()	//数据改变了
{
	ASSERT(NULL != m_pWnd);

	try
	{
		if (m_pRecordSet->IsOpen())
		{
			m_pWnd->SetWindowText(m_Field.GetValue());
		}else
		{
			m_pWnd->SetWindowText(NULL);
		}
	}
	catch (_com_error &e)
	{
		adoShowComError(m_pWnd->m_hWnd, e);
	}
}


void CDBBaseControl::virDataWrite()
{
	//TRACE(_T("----void CDBBaseControl::virDataWrite()\n"));
	CString m_Text;
	CString m_OldText;
	ASSERT(NULL != m_pWnd);

	if (m_pRecordSet->GetAddState() || m_pRecordSet->GetEditChange())
	{
		m_pWnd->GetWindowText(m_Text);
		m_OldText = m_Field.GetValue();
		TRACE(_T("----写入值到数据表中,字段名称:%s\n"), m_strFieldName);

		if (_tcsicmp(m_OldText, m_Text) != 0)
		{
			VERIFY(m_Field.SetValue(m_Text));
			//VERIFY(m_pRecordSet->SetValue(m_FieldName, m_Text));
		}
	}
}


void CDBBaseControl::_OnElseCMDEvents(BASE_CMD nCMD, LPARAM lParam)
{
	ASSERT(NULL != m_pWnd);
	switch(nCMD)
	{
	case BC_CLEAR:
		{
			if (NULL !=	m_pWnd)
			{
				m_pWnd->SetWindowText(_T(""));
			}
		}break;
	case BC_READONLY:
		{
			m_pWnd->EnableWindow((BOOL)lParam);
		}break;
	case BC_EDITCHANGE:
		{
		}break;
	default:
		{
			TRACE(_T("----无法识别的命令\n"));
		}
	}
}


void CDBBaseControl::UpdateField()
{
	if (NULL != m_pRecordSet)
	{
		try
		{
			if (m_pRecordSet->IsOpen())
			{
				m_Field = m_pRecordSet->GetField((LPCTSTR)m_strFieldName);
				virDataChange();
			}
		}catch (_com_error e)
		{
			CAdoError adoError(_T("IDS_FIELD_NOEXIST"), KEY_STRING, theApp.m_resFileName, m_strFieldName);
			adoError.MessageBox(GetActiveWindow(), STR_ADO_CAPTION);
			throw;
		}
	}
}


void CDBBaseControl::SetFieldName(LPCTSTR lpszFieldName)
{ 
	if (m_strFieldName != lpszFieldName)
	{
		m_strFieldName = lpszFieldName;
		UpdateField();
	}
}


BOOL CDBBaseControl::SetAdoRecordset(CAdoRecordset *pRecordset)
{
	ASSERT(NULL != pRecordset);

	if (NULL != pRecordset)
	{
		m_pRecordSet = pRecordset;
		m_pRecordSet->AddView((CDBBaseControl*)this);
		return TRUE;
	}

	return FALSE;
}

bool CDBBaseControl::IsEditMessage(UINT Msg)
{
	switch(Msg)
	{
	case WM_KEYDOWN:
	case WM_CUT:
	case WM_PASTE:
	case WM_UNDO:
		return true;
	}
	return false;
}

void CDBBaseControl::_WinMessage(UINT msg, WPARAM wParam, LPARAM lParam)
{
	if (IsEditMessage(msg))
	{
		if (!m_pRecordSet->GetEditChange())
		{
			m_pRecordSet->SetEditChange(true);
		}return;
	}
	switch(msg)
	{
	case WM_DESTROY:
		{
			ExitRecordset();
		}
	}
}

//////////////////////////////////////////////////////////////////////////
//
//


VOID CAdoRecordset::virDataChange()
{
	POSITION pos	= NULL;
	CDBBaseControl *pBase	= NULL;
	pos = m_List.GetHeadPosition();

	if (GetEnableUpdate())
	{
		while (NULL!=pos)
		{
			pBase = (CDBBaseControl*)m_List.GetNext(pos);
			if (pBase)
			{
				pBase->virDataChange();
			}
		}
	}
}


VOID CAdoRecordset::ChageStruct()
{
	POSITION pos	= NULL;
	CDBBaseControl *pBase	= NULL;
	pos = m_List.GetHeadPosition();

	if (GetEnableUpdate())
	{
		while (NULL!=pos)
		{
			pBase = (CDBBaseControl*)m_List.GetNext(pos);
			if (pBase)
			{
				pBase->ChageStruct();
			}
		}
	}
}


void CAdoRecordset::virDataWrite()
{
	POSITION pos	= NULL;
	CDBBaseControl *pBase	= NULL;
	pos = m_List.GetHeadPosition();

	if (GetEditChange())
	{
		while (NULL != pos)
		{
			pBase = (CDBBaseControl*)m_List.GetNext(pos);
			if (NULL != pBase)
			{
				pBase->virDataWrite();
			}
		}

		m_bEditChange = FALSE;
	}
}


/*void CAdoRecordset::EnableWindow(bool bEnable)
{
	POSITION pos	= NULL;
	CDBBaseControl *pBase	= NULL;
	pos = m_List.GetHeadPosition();

	//ASSERT(bEnable<=TRUE && bEnable>=FALSE);

	if (m_bEnable != bEnable)
	{
		m_bEnable = bEnable;
		while (NULL != pos)
		{
			pBase = (CDBBaseControl*)m_List.GetNext(pos);
			if (pBase)
			{
				pBase->_OnElseCMDEvents(CDBBaseControl::BC_ENABLE, bEnable);
			}
		}
	}
}*/


void CAdoRecordset::UpdateField()
{
	POSITION pos	= NULL;
	CDBBaseControl *pBase	= NULL;
	pos = m_List.GetHeadPosition();

	while (NULL != pos)
	{
		pBase = (CDBBaseControl*)m_List.GetNext(pos);
		if (NULL != pBase)
		{
			pBase->UpdateField();
		}
	}
}


//////////////////////////////////////////////////////////////////////////
//TDBConnectionBaseViews

void TDBConnectionBaseViews::SetAdoConnection(CAdoConnection *pAdoConnection)
{
	POSITION pos;
	TDBConnectionBaseView *pConBase = NULL;
	
	pos = GetHeadPosition();
	while (NULL!=pos)
	{
		pConBase = GetNext(pos);
		pConBase->SetAdoConnection(pAdoConnection);
	}
}


void TDBConnectionBaseViews::ChageTable()
{
	POSITION pos = NULL;
	TDBConnectionBaseView *pConBase = NULL;

	pos = GetHeadPosition();
	while (NULL!=pos)
	{
		pConBase = GetNext(pos);
		pConBase->ChageTable();
	}

}

//CString GetTypeVar(_variant_t vt)
//{
//	switch(vt.vt)
//	{
//	case VT_EMPTY :
//		return _T("VT_EMPTY");
//		break;
//	case   VT_NULL :
//		return _T("VT_NULL");
//		break;
//	case VT_I2:
//		return _T("int");
//		break;
//	case VT_I4 :
//		return _T("long");
//		break;
//	case  VT_R4 :
//		return _T("float");
//		break;
//	case VT_R8 :
//		return _T("double");
//		break;
//	case VT_CY :
//		return _T("currency");
//		break;
//	case VT_DATE:
//		return _T("date");
//		break;
//	case  VT_BSTR :
//		return _T("string");
//		break;
//	case VT_DISPATCH :
//		return _T("dispatch");
//		break;
//	case  VT_ERROR :
//		return _T("error");
//		break;
//	case VT_BOOL :
//		return _T("bool");
//		break;
//	case VT_VARIANT :
//		return _T("variant");
//		break;
//	case VT_UNKNOWN :
//		return _T("unknown");
//		break;
//	case   VT_DECIMAL :
//		return _T("decimal");
//		break;
//	default:
//		return _T("");
//	}
//}

CAdoConnection::CAdoConnection(void)
{
	::CoInitialize(NULL);
	//m_pConn.CreateInstance(__uuidof(Connection));	   
	m_pConn.CreateInstance("ADODB.Connection");
}

CAdoConnection::~CAdoConnection(void)
{
	Close();
	m_pConn.Release();
	m_pConn = NULL;
	
}


void CAdoConnection::AddRecordset(CAdoRecordset *pAdoRecordset)
{
	m_AdoRecordsetLink.AddTail(pAdoRecordset);
}


void CAdoConnection::CloseAllRecordset()
{
	POSITION pos = m_AdoRecordsetLink.GetHeadPosition();
	CAdoRecordset *pRecordset = NULL;

	while (NULL != pos)
	{
		pRecordset = m_AdoRecordsetLink.GetNext(pos);
		if (NULL != pRecordset)
		{
			pRecordset->Close();
		}
	}
}


void CAdoConnection::RemoveRecordset(CAdoRecordset *pAdoRecordset)
{
	m_AdoRecordsetLink.RemoveAt(m_AdoRecordsetLink.Find(pAdoRecordset));
}

/*{Provider=Microsoft.Jet.OLEDB.4.0;
Password=gggggggggg;
User ID=Admin;
Data Source=F:\forever_vc\Test\AdoControl\???.mdb;
Mode=Share Deny None;Extended Properties="";
Persist Security Info=True;Jet OLEDB:System database="";
Jet OLEDB:Registry Path="";
Jet OLEDB:Database Password="";
Jet OLEDB:Engine Type=5;
Jet OLEDB:Database Locking Mode=1;
Jet OLEDB:Global Partial Bulk Ops=2;
Jet OLEDB:Global Bulk Transactions=1;
Jet OLEDB:New Database Password="";
Jet OLEDB:Create System Database=False;
Jet OLEDB:Encrypt Database=False;
Jet OLEDB:Don't Copy Locale on Compact=False;
Jet OLEDB:Compact Without Replica Repair=False;
Jet OLEDB:SFP=False
*/
#define ACCESS_CONN _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;")
#define ACCESS_CONN_USER _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;Jet OLEDB:Database Password=%s")
BOOL CAdoConnection::Open(DatabaseType dt, LPCTSTR lpszName, LPCTSTR UserID, LPCTSTR pwd, long Options)
{
	CString m_ConnStr;
	HRESULT re;
	switch(dt)
	{
	case dtAccess2003:
	case dtAccess97:
	case dtAccessXP:
	case dtAccess2000:
		{
			if (pwd != _T("\0"))
			{
				m_ConnStr.Format(ACCESS_CONN_USER, lpszName, pwd);
			}else
			{
				m_ConnStr.Format(ACCESS_CONN, lpszName);
			}
		}break;
	default:
		return FALSE;
	}
	try
	{
		re = m_pConn->Open(_bstr_t(m_ConnStr), _T(""), _T(""), Options);	
		return re == S_OK;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	} 
	return TRUE;
}


BOOL CAdoConnection::IsConnect()
{
	return (BOOL) m_pConn->GetState() != adStateClosed;
}


CAdoRecordset* CAdoConnection::Execute(LPCTSTR CommandText,long Options)
{
	CAdoRecordset* m_rs= new CAdoRecordset();
	try
	{
		m_rs->SetAdoConnection(this);
#ifdef UNICODE
		m_rs->Open(CommandText, adOpenUnspecified, adLockUnspecified, Options);
#else
		m_rs->Open(_bstr_t(CommandText), adOpenUnspecified, adLockUnspecified, Options);
#endif
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return NULL;
	}
	return m_rs;
}

long CAdoConnection::BeginTrans()
{
	return m_pConn->BeginTrans();
}

void CAdoConnection::RollbackTrans()
{
	m_pConn->RollbackTrans();
}

void CAdoConnection::CommitTrans()
{
	m_pConn->CommitTrans();
}

void CAdoConnection::Cancel()
{
	m_pConn->Cancel();
}


void CAdoConnection::Close()
{
	if (IsConnect())
	{
		CloseAllRecordset();
		m_pConn->Close();
	}
}


void CAdoConnection::SetConnectionTimeout(long ConnectionTimeout)
{
	m_pConn->ConnectionTimeout=ConnectionTimeout;
}


void CAdoConnection::SetConnectionString( LPCTSTR ConnectionString)
{
	m_pConn->ConnectionString=ConnectionString;
}


long CAdoConnection::GetConnectionTimeout()
{
	return m_pConn->ConnectionTimeout;
}


LPCTSTR CAdoConnection::GetConnectionString()
{
	return m_pConn->ConnectionString;
}


void CAdoConnection::GetTableNames(ADO::_RecordsetPtr	&pRset, LPCWSTR lpszType,
								   PGETTABLENAMESPROC pGetTableNamesProc, LPARAM lParam)
{
	_variant_t				_var_Table;
	_variant_t				_var_TableType;
	FieldPtr			_FieldPtr;
	pRset->MoveFirst();
	while ( !pRset->adoEOF)
	{
		_FieldPtr = pRset->Fields->GetItem(L"TABLE_NAME");
		_var_Table = _FieldPtr->GetValue();

		TRACE(_T("表名:%s\n"), _var_Table.bstrVal);

		_FieldPtr		= pRset->Fields->GetItem(L"TABLE_TYPE");
		_var_TableType  = _FieldPtr->GetValue();
		TRACE(L"表类型:%s\n", _var_TableType.bstrVal);

		if (wcscmp(_var_TableType.bstrVal, lpszType)==0) //L"VIEW")==0)
		{
			ASSERT(pGetTableNamesProc);
#ifdef UNICODE
			pGetTableNamesProc(_var_Table.bstrVal, lParam);
#else
			pGetTableNamesProc(_bstr_t(_var_Table.bstrVal), lParam);
#endif
		}
		pRset->MoveNext();
	}
}


BOOL CAdoConnection::GetTableNames(DWORD dwStyle, LPCTSTR lpszCompart,
								   PGETTABLENAMESPROC pGetTableNamesProc, LPARAM lParam)
{
	ADO::_RecordsetPtr	_Rset;
	try 
	{
		if (NULL==pGetTableNamesProc)
			throw TException(_T("指定的过程函数是空值。pGetTableNamesProc\n"));

		_Rset = m_pConn->OpenSchema(adSchemaTables);
		if ( NULL!=_Rset )
		{
			if (dwStyle&AC_TABLE)
			{
				GetTableNames(_Rset, L"TABLE", pGetTableNamesProc, lParam);
			}else if (dwStyle&AC_VIEW)
			{
				if (dwStyle&AC_TABLE)
				{
					pGetTableNamesProc(lpszCompart, lParam);
				}
				GetTableNames(_Rset, L"VIEW", pGetTableNamesProc, lParam);
			}else if(dwStyle&AC_SYSTEM)
			{
				if ((dwStyle&AC_TABLE) || (dwStyle&AC_VIEW))
				{
					pGetTableNamesProc(lpszCompart, lParam);
				}
				GetTableNames(_Rset, L"SYSTEM", pGetTableNamesProc, lParam);
			}
		}
	}
	catch(_com_error e)
	{
		throw e;
	}
	return TRUE;
}


VOID CALLBACK CAdoConnection::GetFieldProc_ComboBox(
					  LPCTSTR lpszFieldName,
					  LPARAM lParam
					  )
{
	ASSERT((HWND)lParam);
	::SendMessage((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)lpszFieldName);
}

VOID CALLBACK CAdoConnection::GetFieldProc_ListBox(
					 LPCTSTR lpszFieldName,
					 LPARAM lParam
					 )
{
	ASSERT((HWND)lParam);
	::SendMessage((HWND)lParam, LB_ADDSTRING, 0, (LPARAM)lpszFieldName);
}

VOID CALLBACK CAdoConnection::GetTableNames_ComboBox(
	LPCTSTR lpszTableName,
	LPARAM lParam
	)
{
	ASSERT((HWND)lParam);
	::SendMessage((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)lpszTableName);
}

VOID CALLBACK CAdoConnection::GetTableNames_ListBox(
	LPCTSTR lpszTableName,
	LPARAM lParam
	)
{
	ASSERT((HWND)lParam);
	::SendMessage((HWND)lParam, LB_ADDSTRING, 0, (LPARAM)lpszTableName);
}

//////////////////////////////////////////////////////////////////////////
//
//***********************************************************************************************
CAdoRecordset::CAdoRecordset(void)
	:m_bAddState(false)
	,m_bEditChange(false)
	,m_bEnableUpdate(true)
	,m_bReadOnly(false)
{
	::CoInitialize(NULL);
	//m_rs.CreateInstance(__uuidof(Recordset));	
	m_rs.CreateInstance("ADODB.Recordset");
	m_Criteria=_T("");
	//m_Eof = true;
	//m_Bof = true;
}
CAdoRecordset::~CAdoRecordset(void)
{
	Close();
	if (m_rs) m_rs.Release();
	m_rs=NULL;
}


BOOL CAdoRecordset::AddNew()
{ 
	ASSERT(true != m_bAddState);

	if (!GetReadOnly())
	{
		if (m_rs->AddNew() == S_OK)
		{
			m_bAddState = true;
			ClearControlValue();
			return TRUE;
		}
	}

	return FALSE;
}


void CAdoRecordset::SetReadOnly(bool bReadOnly)
{
	POSITION  pos = NULL;
	CDBBaseControl *pBase = NULL;
	if (bReadOnly != m_bReadOnly)
	{
		m_bReadOnly = bReadOnly;
		pos = m_List.GetHeadPosition();
		while (NULL != pos)
		{
			pBase = m_List.GetNext(pos);
			pBase->_OnElseCMDEvents(CDBBaseControl::BC_READONLY, !bReadOnly);
		}
	}
}


void CAdoRecordset::SetEditChange(bool bEditChange)
{
	POSITION  pos = NULL;
	CDBBaseControl *pBase = NULL;
	if (bEditChange != m_bEditChange)
	{
		m_bEditChange = bEditChange;
		pos = m_List.GetHeadPosition();
		if (NULL != pos)
		{
			pBase = m_List.GetNext(pos);
			pBase->_OnElseCMDEvents(CDBBaseControl::BC_EDITCHANGE, 0);
		}
	}
}


BOOL CAdoRecordset::Update()
{
	if (m_bEditChange)
	{
		virDataWrite();
		if (m_rs->Update() == S_OK)
		{
			m_bAddState   = false;
			m_bEditChange = false;
			return TRUE;
		}
	}

	return FALSE;
}


void CAdoRecordset::Attach(_RecordsetPtr m_prs )
{
	m_rs=m_prs;
}


BOOL CAdoRecordset::Open(LPCTSTR Source,
						 ADO::CursorTypeEnum CursorType,
						ADO::LockTypeEnum LockType,
						long Options)
{
	if (IsOpen())
	{
		Close();
	}
	HRESULT hr = m_rs->Open(Source, _variant_t((IDispatch*)m_pCon->GetConnection(), TRUE), 
							adOpenStatic, LockType, Options);
	if (hr==S_OK)
	{
		m_pCon->AddRecordset(this);
//		m_Eof = false;
//		m_Bof = true;
		UpdateField();
		virDataChange();	//通知其它控件,数据表数据已经改变,要重新显示数据
		return TRUE;
	}

	return FALSE;
}


void CAdoRecordset::Close()
{
	if(IsOpen())
	{
		HRESULT hr = m_rs->Close();
		if (hr==S_OK)
		{
			SetReadOnly(false);
			SetEnableUpdate(false);
			virDataChange();
			ClearControlValue();

//			m_Eof = true;
//			m_Bof = true;

			m_pCon->RemoveRecordset(this);
		}
	}
}


void CAdoRecordset::ClearControlValue()
{
	POSITION pos = NULL;
	CDBBaseControl *pBase = NULL;
	pos = m_List.GetHeadPosition();

	while (NULL != pos)
	{
		pBase = (CDBBaseControl*)m_List.GetNext(pos);
		if (NULL != pBase)
		{
			pBase->_OnElseCMDEvents(CDBBaseControl::BC_CLEAR, 0);
		}
	}
}


BOOL CAdoRecordset::FindFirst(LPCTSTR Criteria)
{
	MoveFirst();
   	return Find(Criteria,0,adSearchForward,"");
}

//void CAdoRecordset::Move(long NumRecords , _variant_t Start)
//{
//	m_rs->Move(NumRecords,vtMissing);
//}

BOOL CAdoRecordset::FindNext()
{
	return Find(m_Criteria,1,adSearchForward,vtPointer);
}


BOOL CAdoRecordset::Find(LPCTSTR Criteria , long SkipRecords , 
						 SearchDirectionEnum SearchDirection,_variant_t Start)
{
	CString szCri=Criteria;

	if (!szCri.IsEmpty())
		m_Criteria=Criteria;
	else
		return FALSE;
	try{
		m_rs->Find(_bstr_t(Criteria),SkipRecords,SearchDirection,Start);
		if (SearchDirection ==adSearchForward)
		{
			if (!IsEof())
			{
				vtPointer= m_rs->Bookmark;
				return TRUE;
			}
		}else if (SearchDirection ==adSearchBackward)
		{
			if (!IsBof())
			{
				vtPointer= m_rs->Bookmark;
				return TRUE;
			}
		}else return FALSE;

	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
return FALSE;
}



BOOL CAdoRecordset::SetValue(LPCTSTR lpName,CString szCad)
{
	_variant_t vt;
	if(!szCad.IsEmpty())
	{
		vt.vt = VT_BSTR;
		vt.bstrVal = szCad.AllocSysString();
	}

	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,long lVal)
{
	_variant_t vt;
	vt.lVal=lVal;
	vt.vt=VT_I4;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,unsigned char usVal)
{
	_variant_t vt;
	vt.bVal=usVal;
	vt.vt=VT_UI1;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,short shVal)
{
	_variant_t vt;
	vt.iVal=shVal;
	vt.vt=VT_I2;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,float flVal)
{
	_variant_t vt;
	vt.fltVal=flVal;
	vt.vt=VT_R4;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,double dblVal)
{
	_variant_t vt;
	vt.dblVal=dblVal;
	vt.vt=VT_R8;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,BOOL blVal)
{
	_variant_t vt;
	vt.boolVal=blVal;
	vt.vt=VT_BOOL;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,COleDateTime dtVal)
{
	_variant_t vt;
	vt.date=dtVal;
	vt.vt=VT_DATE;	
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName,unsigned long ulVal)
{
	_variant_t vt;
	vt.vt = VT_UI4;
	vt.ulVal = ulVal;
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetValue(LPCTSTR lpName, COleCurrency cuVal)
{
	_variant_t vt;
	vt.vt = VT_CY;
	vt.cyVal = cuVal.m_cur;
	if(cuVal.m_status == COleCurrency::invalid)
		return FALSE;
	return SetFieldValue(lpName, vt);
}

BOOL CAdoRecordset::SetFieldValue(LPCTSTR lpName, _variant_t vtField)
{
	try
	{
		m_rs->Fields->GetItem(lpName)->Value = vtField; 
		return TRUE;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;	
	}
}


CString CAdoRecordset::GetCollect(LPCTSTR lpField)
{
	try{
	_variant_t vt = m_rs->Fields->GetItem(lpField)->Value;
	 return (CString) vt.bstrVal;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return _T("");
	}
 
}

BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,int& nValue)
{
	_variant_t vt;
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_I2)
		{
			nValue=vt.intVal;
			return TRUE;
		}else if (vt.vt==VT_BOOL)
		{
			nValue=vt.boolVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,long& lVal)
{
	_variant_t vt;
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_I4)
		{
			lVal=vt.lVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}
BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,double& dbVal)
{
	_variant_t vt;
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_R8)
		{
			dbVal=vt.dblVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,CString& strValue)
{
	_variant_t vt;
	try
	{	
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_BSTR)
		{
			strValue=vt.bstrVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}


BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,COleCurrency& cyVal)
{
	_variant_t vt;
	vt = m_rs->Fields->GetItem(lpField)->Value;
	
	try
	{
		if (vt.vt==VT_CY)
		{
			cyVal.m_cur=vt.cyVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,COleDateTime& dtVal)
{
	_variant_t vt;
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_DATE)
		{
			dtVal=vt.date;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,float& flVal)
{
	_variant_t vt;
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		if (vt.vt==VT_R4)
		{
			flVal=vt.fltVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CAdoRecordset::GetCollect(LPCTSTR lpField,_variant_t& vt)
{
	try
	{
		vt = m_rs->Fields->GetItem(lpField)->Value;
		return TRUE;
	}
	catch(_com_error& e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
	
BOOL CAdoRecordset::GetCollect(int nIndex,int& nValue)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_I2)
		{
			nValue=vt.intVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CAdoRecordset::GetCollect(int nIndex,long& lVal)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_I4)
		{
			lVal=vt.lVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CAdoRecordset::GetCollect(int nIndex,double& dbVal)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_R8)
		{
			dbVal=vt.dblVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CAdoRecordset::GetCollect(int nIndex,CString& strValue)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{	
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_BSTR)
		{
			strValue=vt.bstrVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CAdoRecordset::GetCollect(int nIndex,COleCurrency& cyVal)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_CY;
	try
	{
		vtn.iVal =nIndex;
		vt	= m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_CY)
		{
			cyVal.m_cur=vt.cyVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CAdoRecordset::GetCollect(int nIndex,COleDateTime& dtVal)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_DATE)
		{
			dtVal=vt.date;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
		
}

BOOL CAdoRecordset::GetFormatDate(LPCTSTR lpField,CString& m_szDate, CString Format)
{
	COleDateTime time;
	if (!GetCollect(lpField,time)) return FALSE;
	CTime ct(time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); 
	m_szDate =ct.Format(Format);
	return TRUE;
}

BOOL CAdoRecordset::GetFormatDate(int nIndex,CString& m_szDate, CString Format)
{
	COleDateTime time;
	if (!GetCollect(nIndex,time)) return FALSE;
	CTime ct(time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); 
	m_szDate =ct.Format(Format);
	return TRUE;
}

BOOL CAdoRecordset::GetCollect(int nIndex,float& flVal)
{
	_variant_t vt;
	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		if (vt.vt==VT_R4)
		{
			flVal=vt.fltVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}



BOOL CAdoRecordset::GetCollect(int nIndex,_variant_t& vt)
{

	_variant_t vtn;
	vtn.vt = VT_I2;
	try
	{
		vtn.iVal = nIndex;
		vt = m_rs->Fields->GetItem(vtn)->Value;
		return TRUE;
	}
	catch(_com_error& e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
	


BOOL CAdoRecordset::SetFilter(LPCTSTR lpFilter)
{
	if (!IsOpen()) return FALSE;
	try
	{
		m_rs->PutFilter(lpFilter);
		return TRUE;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CAdoRecordset::SetSort(LPCTSTR lpSort)
{
	if (!IsOpen()) return FALSE;
	try
	{
		m_rs->PutSort(lpSort);
		return TRUE;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
	

BOOL CAdoRecordset::IsOpen()
{
	if(m_rs)
		return m_rs-> GetState() != adStateClosed;
	return FALSE;
}


void CAdoRecordset::InitBof()
{
	//try
	//{
	//	int nCur    = m_rs->GetAbsolutePosition();
	//	int nCount  = m_rs->GetRecordCount();

	//	if (nCount>=1)
	//	{
	//		if ((nCur <= nCount) && (nCur1>=1) )
	//		{
	//			if (nCount==1) //只存在一条记录。
	//			{
	//				m_Eof = true;
	//				m_Bof = true;
	//			}else
	//			{
	//				m_Eof = false;
	//				m_Bof = false;
	//			}
	//		}else
	//		{
	//		}

	//	}

	//}catch (...) {
	//}
}


void CAdoRecordset::MoveFirst()
{
	virDataWrite();

	if (!IsBof())
	{
		m_rs->MoveFirst();
		virDataChange();
//		m_Bof = true;
		
		if (m_rs->Supports(ADO::adMovePrevious) && (!IsBof()))
		{
			m_rs->MovePrevious();
		}
	}	
}


void CAdoRecordset::MoveLast()
{
	virDataWrite();

	if (!IsEof())
	{
		m_rs->MoveLast();
		virDataChange();
//		m_Eof = true;

		if (!IsEof())
		{
			m_rs->MoveNext();
		}
	}	
}


void CAdoRecordset::MoveNext()
{
	virDataWrite();

	if (!IsEof())
	{
		m_rs->MoveNext();
		if (!IsEof())
		{
			virDataChange();

			if (m_rs->GetRecordCount() == m_rs->GetAbsolutePosition())
			{
//				m_Eof = true;
				m_rs->MoveNext();
			}
//			else
//			{
//				m_Eof = false;
///			}
		}
	}	
}


void CAdoRecordset::MovePrevious()
{
	virDataWrite();

	if (!IsBof())
	{
		m_rs->MovePrevious();
		if (!IsBof())
		{
			virDataChange();

			if (m_rs->GetAbsolutePosition() == 1)
			{
				m_rs->MovePrevious();
//				m_Bof = true;
			}
			//else
			//{
//				m_Bof = false;
			//}
		}
	}	
}

void CAdoRecordset::Cancel()
{
   m_rs->Cancel();
   virDataChange();
}

void CAdoRecordset::CancelUpdate()
{
	m_rs->CancelUpdate();
}


//BOOL CAdoRecordset::OnDelete(int nRecord)
//{
//	CString _Hint;
//	CString _Src;
//	_Src = LoadIniStr(_T("IDS_DELETE_RECNO"), KEY_STRING, theApp.m_resFileName);
//	_Hint.Format(_Src, lRecord);
//
//	if (MessageBox(GetActiveWindow(), _Hint, _T(""), MB_OKCANCEL|MB_ICONQUESTION))
//	{
//		return TRUE;
//	}
//
//	return FALSE;
//}
//

BOOL CAdoRecordset::Delete()
{
	ADO::PositionEnum pe;
	try
	{
		if (m_rs->GetRecordCount() > 0)
		{
			//在这里修正一个当前记录号。
			pe = m_rs->GetAbsolutePosition();
			if ( ADO::adPosBOF == pe)
			{
				m_rs->MoveNext();
			}else if(ADO::adPosEOF==pe)
			{
				m_rs->MovePrevious();
			}else if(ADO::adPosUnknown==pe)
			{
				return FALSE;
			}

			if	(m_rs->Delete(adAffectCurrent)== S_OK)
			{
				if(m_rs->Update() == S_OK)
				{
					if (0<m_rs->GetRecordCount())
					{
						m_rs->MoveNext();
						if (IsEof())
						{
							m_rs->MovePrevious();
						}
						virDataChange();
					}else
					{
						ClearControlValue();
					}
					return TRUE;
				}
			}			
		}
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
	}

	return FALSE;
}


//#define STR_FIELDNAME_EXIST _T("\"%s\" - 字段名称不存在。")

CField CAdoRecordset::GetField(LPCTSTR lpField)
{
	FieldPtr pField = m_rs->Fields->GetItem(lpField);
	CField Field;
	if (NULL == pField)
	{
		throw CAdoError(_T("IDS_FILE_NOEXIST"), KEY_STRING, theApp.m_resFileName, lpField);
	}
	Field.Attach(pField);
	return Field;
}


CField CAdoRecordset::GetField(int Index)
{
	_variant_t vtIndex;
	vtIndex.vt = VT_I2;
	vtIndex.iVal = Index;
	FieldPtr pField = m_rs->Fields->GetItem(vtIndex);
	if (NULL == pField)
	{
		throw CAdoError(_T("IDS_FILE_NOEXIST"), KEY_STRING, theApp.m_resFileName, _T("Index"));
	}
	CField Field;
	Field.Attach(pField);
	return Field;
}


CAdoRecordset*  CAdoRecordset::Clone(ADO::LockTypeEnum LockType)
{
	_RecordsetPtr m_rs1=m_rs->Clone(LockType);
	CAdoRecordset* m_pRs= new CAdoRecordset();
	m_pRs->Attach(m_rs1);
	return m_pRs; 
}


CAdoRecordset* CAdoRecordset::NextRecordset(long RecordsAffected) 
{
	_RecordsetPtr m_rs1=m_rs->NextRecordset((VARIANT*)RecordsAffected);
	CAdoRecordset* m_pRs= new CAdoRecordset();
	m_pRs->Attach(m_rs1);
	return m_pRs; 
}

// add 
BOOL CAdoRecordset::AppendChunk(FieldPtr pField, LPVOID lpData, UINT nBytes)
{
	SAFEARRAY FAR *pSafeArray = NULL;
	SAFEARRAYBOUND rgsabound[1];

	try
	{
		rgsabound[0].lLbound = 0;
		rgsabound[0].cElements = nBytes;
		pSafeArray = SafeArrayCreate(VT_UI1, 1, rgsabound);

		for (long i = 0; i < (long)nBytes; i++)
		{
			UCHAR &chData	= ((UCHAR*)lpData)[i];
			HRESULT hr = SafeArrayPutElement(pSafeArray, &i, &chData);
			if (FAILED(hr))	return FALSE;
		}

		_variant_t varChunk;
		varChunk.vt = VT_ARRAY | VT_UI1;
		varChunk.parray = pSafeArray;
		
		return (pField->AppendChunk(varChunk) == S_OK);
	}
	catch (_com_error &e)
	{
		TRACE(_T("Warning: AppendChunk 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
		return FALSE;
	}
}


BOOL CAdoRecordset::AppendChunk(long index, LPVOID lpData, UINT nBytes)
{
	ASSERT(m_rs != NULL);
	ASSERT(lpData != NULL);
	if (GetFieldAttributes(index)&adFldLong)
	{
		return AppendChunk(GetField(index).GetFieldPtr(), lpData, nBytes);
	}
	else return FALSE;
}


BOOL CAdoRecordset::AppendChunk(LPCTSTR strFieldName, LPVOID lpData, UINT nBytes)
{
	ASSERT(m_rs != NULL);
	ASSERT(lpData != NULL);
	if (adFldLong & GetFieldAttributes(strFieldName))
	{
		return AppendChunk(GetField(strFieldName).GetFieldPtr(), lpData, nBytes);
	}
	else return FALSE;
}


BOOL CAdoRecordset::AppendChunk(long index, LPCTSTR lpszFileName)
{
	ASSERT(m_rs != NULL);
	ASSERT(lpszFileName != NULL);
	BOOL bret = FALSE;
	if (adFldLong & GetFieldAttributes(index))
	{
		CFile file;
		if (file.Open(lpszFileName, CFile::modeRead))
		{
			long length = (long)file.GetLength();
			char *pbuf = new char[length];
			if (pbuf != NULL && file.Read(pbuf, length) == (DWORD)length)
			{
				bret = AppendChunk(GetField(index).GetFieldPtr(), pbuf, length);
			}
			if (pbuf != NULL) delete[] pbuf;
		}
		file.Close();
	}
	return bret;
}


BOOL CAdoRecordset::AppendChunk(LPCTSTR strFieldName, LPCTSTR lpszFileName)
{
	ASSERT(m_rs != NULL);
	ASSERT(lpszFileName != NULL);
	BOOL bret = FALSE;

	if (adFldLong & GetFieldAttributes(strFieldName))
	{
		CFile file;
		if (file.Open(lpszFileName, CFile::modeRead))
		{
			long length = (long)file.GetLength();
			char *pbuf = new char[length+1];
			if (pbuf != NULL && file.Read(pbuf, length) == (DWORD)length)
			{
				bret = AppendChunk(GetField(strFieldName).GetFieldPtr(), pbuf, length);
			}
			if (pbuf != NULL) delete[] pbuf;
		}
		file.Close();
	}
#ifdef _DEBUG
	else
	{
		::MessageBox(NULL, _T("字段类型不是 \"Ole\"数据类型,无法写入数据。"), _T(""), MB_OK|MB_ICONERROR);
	}
#endif

	return bret;
}


BOOL CAdoRecordset::GetChunk(FieldPtr pField, LPVOID lpData)
{
	ASSERT(pField != NULL);
	ASSERT(lpData != NULL);

	UCHAR chData;
	long index = 0;

	while (index < pField->ActualSize)
	{ 
		try
		{
			_variant_t varChunk = pField->GetChunk(100);
			if (varChunk.vt != (VT_ARRAY | VT_UI1))
			{
				return FALSE;
			}

			for (long i = 0; i < 100; i++)
			{
				if (SUCCEEDED( SafeArrayGetElement(varChunk.parray, &i, &chData) ))
				{
					((UCHAR*)lpData)[index] = chData;
					index++;
				}
				else
				{
					break;
				}
			}
		}
		catch (_com_error e)
		{
			TRACE(_T("Warning: GetChunk 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
			return FALSE;
		}
	}

	return TRUE;
}


BOOL CAdoRecordset::GetChunk(long index, LPVOID lpData)
{
	if (adFldLong & GetFieldAttributes(index))
		return  GetChunk(GetField(index).GetFieldPtr(), lpData);
	else return FALSE;
}


BOOL CAdoRecordset::GetChunk(LPCTSTR strFieldName, LPVOID lpData)
{
	if (adFldLong & GetFieldAttributes(strFieldName))
		return  GetChunk(GetField(strFieldName).GetFieldPtr(), lpData);
	else return FALSE;
}


//BOOL CAdoRecordset::GetChunk(long index, CBitmap &bitmap)
//{
//	return GetChunk(GetFieldName(index), bitmap);
//}

BOOL CAdoRecordset::GetChunk(LPCTSTR strFieldName, CBitmap &bitmap)
{		
	BOOL bret = FALSE;
	long size = GetFieldActualSize(strFieldName);
	if ((adFldLong & GetFieldAttributes(strFieldName)) && size > 0)
	{
		BYTE *lpData = new BYTE[size];

		if (GetChunk(GetField(strFieldName).GetFieldPtr(), (LPVOID)lpData))
		{
			BITMAPFILEHEADER bmpHeader;
			DWORD bmfHeaderLen = sizeof(bmpHeader);
			strncpy((LPSTR)&bmpHeader, (LPSTR)lpData, bmfHeaderLen);

			// 是否是位图 ----------------------------------------
			if (bmpHeader.bfType == (*(WORD*)"BM"))
			{
				BYTE* lpDIBBits = lpData + bmfHeaderLen;
				BITMAPINFOHEADER &bmpiHeader = *(LPBITMAPINFOHEADER)lpDIBBits;
				BITMAPINFO &bmpInfo = *(LPBITMAPINFO)lpDIBBits;
				lpDIBBits = lpData + ((BITMAPFILEHEADER *)lpData)->bfOffBits;

				// 创建位图 --------------------------------------
				CDC dc;
				HDC hdc = GetDC(NULL);
				dc.Attach(hdc);
				HBITMAP hBmp = CreateDIBitmap(dc.m_hDC, &bmpiHeader, CBM_INIT, lpDIBBits, &bmpInfo, DIB_RGB_COLORS);
				if (bitmap.GetSafeHandle() != NULL) bitmap.DeleteObject();
				bitmap.Attach(hBmp);
				dc.Detach();
				ReleaseDC(NULL, hdc);
				bret = TRUE;
			}
		}
		delete[] lpData;
		lpData = NULL;
	}
	return bret;
}


/*========================================================================
name:		取得 Field 对象一项或多项属性.
----------------------------------------------------------
returns:	对于 Field 对象, Attributes 属性为只读, 其值可能为以下任意
一个或多个 FieldAttributeEnum 值的和.
[常量]				[说明] 
-------------------------------------------
adFldMayDefer			指示字段被延迟, 即不从拥有整个记录的数据源检索
字段值, 仅在显式访问这些字段时才进行检索. 
adFldUpdatable		指示可以写入该字段. 
adFldUnknownUpdatable 指示提供者无法确定是否可以写入该字段. 
adFldFixed			指示该字段包含定长数据. 
adFldIsNullable		指示该字段接受 Null 值. 
adFldMayBeNull		指示可以从该字段读取 Null 值. 
adFldLong				指示该字段为长二进制字段. 并指示可以使用 AppendChunk 
和 GetChunk 方法. 
adFldRowID			指示字段包含持久的行标识符, 该标识符无法被写入
并且除了对行进行标识(如记录号、唯一标识符等)外不
存在有意义的值. 
adFldRowVersion		指示该字段包含用来跟踪更新的某种时间或日期标记. 
adFldCacheDeferred	指示提供者缓存了字段值, 并已完成随后对缓存的读取. 
==========================================================================*/
long CAdoRecordset::GetFieldAttributes(long lIndex)
{
	ASSERT(m_rs != NULL);
	try
	{

		return m_rs->Fields->GetItem(_variant_t(lIndex))->GetAttributes();
	}
	catch (_com_error e)
	{
		TRACE(_T("Warning: GetFieldAttributes 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
		return -1;
	}
}


long CAdoRecordset::GetFieldAttributes(LPCTSTR lpszFieldName)
{
	ASSERT(m_rs != NULL);
	try
	{
		return m_rs->Fields->GetItem(_variant_t(lpszFieldName))->GetAttributes();
	}
	catch (_com_error e)
	{
		TRACE(_T("Warning: GetFieldAttributes 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
		return -1;
	}
}

/*========================================================================
Name:	取得字段的值的实际长度.
----------------------------------------------------------
returns:	返回长整型值.某些提供者允许设置该属性以便为 BLOB 数据预留
空间, 在此情况下默认值为 0.
----------------------------------------------------------
Remarks:	使用 ActualSize 属性可返回 Field 对象值的实际长度.对于所有
字段,ActualSize 属性为只读.如果 ADO 无法确定 Field 对象值的实
际长度, ActualSize 属性将返回 adUnknown.
如以下范例所示, ActualSize 和  DefinedSize 属性有所不同: 
adVarChar 声明类型且最大长度为 50 个字符的 Field 对象将返回为 
50 的 DefinedSize 属性值, 但是返回的 ActualSize 属性值是当前记
录的字段中存储的数据的长度.
==========================================================================*/
long CAdoRecordset::GetFieldActualSize(long lIndex)
{
	ASSERT(m_rs != NULL);
	try
	{
		return m_rs->Fields->GetItem(_variant_t(lIndex))->ActualSize;
	}
	catch (_com_error e)
	{
		TRACE(_T("Warning: GetFieldActualSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
		return -1;
	}
}


long CAdoRecordset::GetFieldActualSize(LPCTSTR lpszFieldName)
{
	ASSERT(m_rs != NULL);
	try
	{
		return m_rs->Fields->GetItem(_variant_t(lpszFieldName))->ActualSize;
	}
	catch (_com_error e)
	{
		TRACE(_T("Warning: GetFieldActualSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
		return -1;
	}	
}


//***********************************************************************************************************
CField::CField(void)
:field(NULL)
{
}
CField::~CField(void)
{
}
BOOL CField::SetValue(long lVal)
{
	_variant_t vt;
	vt.lVal=lVal;
	vt.vt=VT_I4;	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}



BOOL CField::SetValue(float flVal)
{
	_variant_t vt;
	vt.fltVal=flVal;
	vt.vt=VT_R4;	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}


BOOL CField::SetValue(int nVal)
{
	_variant_t vt;
	vt.intVal=nVal;
	vt.vt=VT_I2;	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

	
}

BOOL CField::SetValue(double dbVal)
{
	_variant_t vt;
	vt.dblVal=dbVal;
	vt.vt=VT_R8;	
	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CField::SetValue(CString szCad)
{
	_variant_t vt;
	if(!szCad.IsEmpty())
	{
		vt.vt = VT_BSTR;
		vt.bstrVal = szCad.AllocSysString();
	}
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}


}


BOOL CField::SetValue(bool blVal)
{
	_variant_t vt;
	vt.boolVal=blVal;
	vt.vt=VT_BOOL;	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}


BOOL CField::SetValue(COleDateTime dtVal)
{
	_variant_t vt;
	vt.date=dtVal;
	vt.vt=VT_DATE;	
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CField::SetValue(_variant_t vt)
{
	try
	{
		field->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}


CString CField::GetValue()
{
	CString m_strFieldValue;
	_variant_t m_varFieldValue;
	m_varFieldValue = field->GetValue();

	switch (m_varFieldValue.vt)
	{
	case VT_BSTR://字符串
	case VT_LPSTR://字符串
	case VT_LPWSTR://字符串
		m_strFieldValue = (LPCTSTR)(_bstr_t)m_varFieldValue;
		break;
	case VT_I1:
	case VT_UI1:
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.bVal);
		break;
	case VT_I2://短整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.iVal);
		break;
	case VT_UI2://无符号短整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.uiVal);
		break;
	case VT_INT://整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.intVal);
		break;
	case VT_I4: //整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.lVal);
		break;
	case VT_I8: //长整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.lVal);
		break;
	case VT_UINT://无符号整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.uintVal);
		break;
	case VT_UI4: //无符号整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.ulVal);
		break;
	case VT_UI8: //无符号长整型
		m_strFieldValue.Format(_T("%d"), m_varFieldValue.ulVal);
		break;
	case VT_VOID:
		m_strFieldValue.Format(_T("%8x"), m_varFieldValue.byref);
		break;
	case VT_R4://浮点型
		m_strFieldValue.Format(_T("%.4f"), m_varFieldValue.fltVal);
		break;
	case VT_R8://双精度型
		m_strFieldValue.Format(_T("%.8f"), m_varFieldValue.dblVal);
		break;
	case VT_DECIMAL: //小数
		m_strFieldValue.Format(_T("%.8f"), (double)m_varFieldValue);
		break;
	case VT_CY:
		{
			COleCurrency m_OldCy;
			m_OldCy = m_varFieldValue.cyVal;
			m_strFieldValue = m_OldCy .Format();
		}
		break;
	case VT_BLOB:
	case VT_BLOB_OBJECT:
	case 0x2011:
		m_strFieldValue = _T("[BLOB]");
		break;
	case VT_BOOL://布尔型

		m_strFieldValue = m_varFieldValue.boolVal ? _T("TRUE") : _T("FALSE");
		break;
	case VT_DATE: //日期型
		{		
			COleDateTime m_da;

			m_da = COleDateTime(m_varFieldValue.date); 
			m_strFieldValue = m_da.Format(_T("%Y-%m-%d %H:%M:%S"));
		}
		break;
	case VT_NULL://NULL值
		m_strFieldValue = _T("");
		break;
	case VT_EMPTY://空
		m_strFieldValue = _T("");
		break;
	case VT_UNKNOWN://未知类型
	default:
		m_strFieldValue = _T("UN_KNOW");
		break;
	}
	return m_strFieldValue;
}


BOOL CField::GetValue(int& nVal)
{
	_variant_t vt;
	vt = field->Value;
	try
	{
		if (vt.vt==VT_I2)
		{
			nVal=vt.intVal;
			return TRUE;
		}else if (vt.vt==VT_BOOL)
		{
			nVal=vt.boolVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CField::GetValue(long& lVal)
{
	_variant_t vt;
	vt = field->Value;
	try
	{
		if (vt.vt==VT_I4)
		{
			lVal=vt.lVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CField::GetValue(double& dbVal)
{
	_variant_t vt;
	vt = field->Value;
	try
	{
		if (vt.vt==VT_R8)
		{
			dbVal=vt.dblVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CField::GetValue(CString& strValue)
{
	_variant_t vt;
	vt =field->Value;
	
	try
	{
		if (vt.vt==VT_BSTR)
		{
			strValue=vt.bstrVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CField::GetValue(COleDateTime& dtVal)
{
	_variant_t vt;
	vt = field->Value;
	try
	{
		if (vt.vt==VT_DATE)
		{
			dtVal=vt.date;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
		
}

BOOL CField::GetValue(float& flVal)
{
	_variant_t vt;
	vt = field->Value;
	try
	{
		if (vt.vt==VT_R4)
		{
			flVal=vt.fltVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}



BOOL CField::GetValue(_variant_t& vt)
{
	try
	{
		//_variant_t vt = field->Value;
		vt = field->Value;
		return TRUE;
	}
	catch(_com_error& e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
	

//***********************************************************************************************************

CGuiParameter::CGuiParameter()
{
	::CoInitialize(NULL);
	//pParam.CreateInstance(__uuidof(Parameter));	
}

CGuiParameter::~CGuiParameter()
{
	pParam->Release();
	pParam=NULL;
}


void CGuiParameter::SetAttributes(long Attributes)
{
	pParam->PutAttributes(Attributes);
}

void CGuiParameter::SetDirection(ADO::ParameterDirectionEnum Direction)
{
	pParam->PutDirection(Direction);
}

void CGuiParameter::SetName(LPCTSTR szName)
{
	CString mszname=szName;
	pParam->Name=mszname.AllocSysString();
	
}

void CGuiParameter::SetNumericScale(unsigned char NumericScale)
{
	pParam->PutNumericScale(NumericScale);
}

void CGuiParameter::SetPrecision(unsigned char Precision)
{
	pParam->PutPrecision(Precision);
}

void CGuiParameter::SetSize(long Size)
{
	pParam->PutSize(Size);
}

void CGuiParameter::SetType(ADO::DataTypeEnum Type)
{
	pParam->PutType(Type);
}

BOOL CGuiParameter::SetValue(long lVal)
{
	_variant_t vt;
	vt.lVal=lVal;
	vt.vt=VT_I4;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}



BOOL CGuiParameter::SetValue(float flVal)
{
	_variant_t vt;
	vt.fltVal=flVal;
	vt.vt=VT_R4;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}


BOOL CGuiParameter::SetValue(int nVal)
{
	_variant_t vt;
	vt.intVal=nVal;
	vt.vt=VT_I2;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

	
}

BOOL CGuiParameter::SetValue(double dbVal)
{
	_variant_t vt;
	vt.dblVal=dbVal;
	vt.vt=VT_R8;	
	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::SetValue(CString szCad)
{
	_variant_t vt;
	if(!szCad.IsEmpty())
	{
		vt.vt = VT_BSTR;
		vt.bstrVal = szCad.AllocSysString();
	}
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}


}


BOOL CGuiParameter::SetValue(bool blVal)
{
	_variant_t vt;
	vt.boolVal=blVal;
	vt.vt=VT_BOOL;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}


BOOL CGuiParameter::SetValue(COleDateTime dtVal)
{
	_variant_t vt;
	vt.date=dtVal;
	vt.vt=VT_DATE;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::SetValue(_variant_t vt)
{
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::GetValue(int& nVal)
{
	_variant_t vt;
	vt = pParam->Value;
	try
	{
		if (vt.vt==VT_I2)
		{
			nVal=vt.intVal;
			return TRUE;
		}else if (vt.vt==VT_BOOL)
		{
			nVal=vt.boolVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::GetValue(long& lVal)
{
	_variant_t vt;
	vt = pParam->Value;
	try
	{
		if (vt.vt==VT_I4)
		{
			lVal=vt.lVal;
			return TRUE;
		}if (vt.vt==VT_BSTR)
		{
			CString cad(vt.bstrVal);
			//lVal=atol(cad);
			lVal=_ttol(cad);
			return TRUE;
		}
		else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::SetValue(COleCurrency cyVal)
{
	_variant_t vt;
	vt.cyVal=cyVal.m_cur;
	vt.vt=VT_CY;	
	try
	{
		pParam->Value=vt;
		return TRUE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

BOOL CGuiParameter::GetValue(double& dbVal)
{
	_variant_t vt;
	vt = pParam->Value;
	try
	{
		if (vt.vt==VT_R8)
		{
			dbVal=vt.dblVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CGuiParameter::GetValue(CString& strValue)
{
	_variant_t vt;
	vt =pParam->Value;
	
	try
	{
		if (vt.vt==VT_BSTR)
		{
			strValue=vt.bstrVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}

BOOL CGuiParameter::GetValue(COleDateTime& dtVal)
{
	_variant_t vt;
	vt = pParam->Value;
	try
	{
		if (vt.vt==VT_DATE)
		{
			dtVal=vt.date;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
		
}

BOOL CGuiParameter::GetValue(COleCurrency& cyVal)
{
	_variant_t vt;
	vt = pParam->Value;
	
	try
	{
		if (vt.vt==VT_CY)
		{
			cyVal.m_cur=vt.cyVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}


BOOL CGuiParameter::GetFormatDate(CString& m_szDate, CString Format)
{
	COleDateTime time;
	if (!GetValue(time)) return FALSE;
	CTime ct(time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); 
	m_szDate =ct.Format(Format);
	return TRUE;
}



BOOL CGuiParameter::GetValue(float& flVal)
{
	_variant_t vt;
	vt = pParam->Value;
	try
	{
		if (vt.vt==VT_R4)
		{
			flVal=vt.fltVal;
			return TRUE;
		}else return FALSE;
	}catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}



BOOL CGuiParameter::GetValue(_variant_t& vt)
{
	try
	{
		_variant_t vt = pParam->Value;
		return TRUE;
	}
	catch(_com_error& e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}
}
	

//----------------------------------------------------------------------------------------------

CGuiCommand::CGuiCommand()
{
	::CoInitialize(NULL);
	//pCommand.CreateInstance(__uuidof(Command));	

}

CGuiCommand::~CGuiCommand()
{
	Cancel();
	pCommand->Release();
	pCommand=NULL;
}


void CGuiCommand::SetActiveConnection(LPCTSTR szconnec)
{
//	m_pCon.Open(szconnec, _T(""), _T(""), -1);

	ASSERT( m_pCon.IsConnect());
	SetActiveConnection(&m_pCon);
}


void CGuiCommand::SetActiveConnection(CAdoConnection* pCon)
{
	ASSERT(pCon->IsConnect());
	pCommand->ActiveConnection=pCon->GetConnection();
}

void CGuiCommand::Cancel()
{
	pCommand->Cancel();
} 

void CGuiCommand::SetCommandText(LPCTSTR lpCommand,CommandTypeEnum cmdType)
{
	CString szCommand=lpCommand;
	pCommand->CommandText=szCommand.AllocSysString();
	pCommand->PutCommandType(cmdType);
}

void CGuiCommand::SetCommandTimeout(long CommandTimeout)
{
	pCommand->PutCommandTimeout(CommandTimeout);
}

void CGuiCommand::SetPrepared(BOOL prepared)
{
	pCommand->PutPrepared((BOOL) prepared);
}

long CGuiCommand::GetState()
{
	return pCommand->GetState();
}

CAdoRecordset* CGuiCommand::Execute(VARIANT* param1,VARIANT* param2,long Options)
{
	try
	{
		_RecordsetPtr m_rs = pCommand->Execute(NULL, NULL, Options);
		CAdoRecordset* m_prs= new CAdoRecordset();
		m_prs->Attach(m_rs);
		return m_prs;
	}
	catch(_com_error &e)
	{
		adoShowComError(NULL, e);
		return NULL;
	}
	
}

CGuiParameter* CGuiCommand::CreateParameter(CString Name ,long Size ,
											ADO::DataTypeEnum Type, 
											ADO::ParameterDirectionEnum Direction)
{
	_ParameterPtr param=pCommand->CreateParameter(Name.AllocSysString(), Type,Direction, Size);
		
	CGuiParameter* pParam=new CGuiParameter();
	pParam->Attach(param);
	return pParam;
}
	
BOOL CGuiCommand::Append(CGuiParameter* pParam)
{
	try
	{
		pCommand->Parameters->Append(pParam->GetParameter());
		return TRUE;
	}
	catch(_com_error& e)
	{
		adoShowComError(NULL, e);
		return FALSE;
	}

}

//////////////////////////////////////////////////////////////////////////

ADOX::_ColumnPtr
WINAPI
adoFindColumn(
			  ADOX::ColumnsPtr &pColumnsPtr,
			  LPCTSTR lpszColumnName
			  )
{
	_variant_t			_varItem;
	long				_IndexItem;
	long				_ItemCount = pColumnsPtr->GetCount();	
	ADOX::_ColumnPtr	_pColumn;

	_varItem.vt = VT_I4;
	for (_IndexItem=0; _IndexItem<_ItemCount; _IndexItem)
	{
		_pColumn = pColumnsPtr->GetItem(_varItem);		

		//if (0==wcscmp(pColumnsPtr->GetItem(_var_Item)->GetName(), lpszColumnName))
		
		if (0==_tcscmp(_pColumn->GetName(), lpszColumnName))
		{
			return _pColumn;
		}
	}

	return _pColumn;
}

BOOL 
WINAPI
adoWriteOleDataDialog(
					  CWnd *pWnd,
					  CAdoRecordset &RecordSet,
					  LPCWSTR lpszFieldName)
{
	CFileDialogEx dlg(TRUE, NULL, NULL, 
		OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
		_T("JPG Files (*.jpg)|*.jpg|BMP File (*.bmp)|*.bmp||"), pWnd);	
	if (dlg.DoModal() == IDOK)
	{
		if (RecordSet.AppendChunk((LPCTSTR)lpszFieldName, dlg.GetPathName()))
		{
			return TRUE;
		}
	}
	return FALSE;
}

BOOL WINAPI DbRegisterClass(LPCTSTR lpszClassName)
{
	HINSTANCE	hInstance;
	hInstance	= AfxGetInstanceHandle();
	WNDCLASS	wc;

	if (!(::GetClassInfo(hInstance, lpszClassName, &wc)))
	{
		wc.cbClsExtra	= 0;
		wc.cbWndExtra	= 0;
		wc.hbrBackground= (HBRUSH)COLOR_WINDOW;
		wc.hCursor		= AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		wc.hIcon		= NULL;
		wc.hInstance	= hInstance;
		wc.lpfnWndProc	= ::DefWindowProc;
		wc.lpszClassName= lpszClassName;
		wc.lpszMenuName = NULL;
		wc.style		= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

		if (!AfxRegisterClass(&wc))
		{
			AfxThrowResourceException();
			return FALSE;
		}
	}
	return TRUE;
}

CString WINAPI AdoGetFormatWhere(LPCTSTR lpszFieldName, ADO::DataTypeEnum dte, LPCTSTR lpszSymbol, LPCTSTR lpszFieldValue)
{
	CString _Where;
	if (0==_tccmp(lpszSymbol, _T("Is NULL")))
	{
		_Where.Format(_T("%s %s"), lpszFieldName, lpszSymbol);	//字段名 is NULL;
	}else
	{
		switch(dte)
		{
		case adArray:	//_T("全安数组");
		case adBigInt:  //_T("8 字节带符号的整数");
			{
			}break;
		case adBinary:	//_T("二进制");
		case adBoolean:	//_T("布尔型");

			//		case adByRef:
			//		{
			//			lpFieldInfo->nFieldType = ;adb
			//			lpFieldInfo->strTypeName= _T("");
			//			lpFieldInfo->strExplain = _T("与其他类型一起加入逻辑 OR 以指示该数据是其他类型数"	据的指针 (DBTYPE_BYREF). ");
			//		}break;
		case adLongVarChar:		//_T("长字符串值. ");
		case adLongVarWChar:	//_T("以空结尾的长字符串值. ");

			break;
		case adBSTR:	//_T("宽字符串");
		case adChar:	//_T("文本");
		case adVarChar:				//_T("字符串值. ");
		case adVarWChar:		//_T("以空结尾的 Unicode 字符串. ");
		case adWChar:			//_T("以空结尾的 Unicode 字符串 (DBTYPE_WSTR). ");
			{
				// 字段名='值';
				_Where.Format(_T("%s%s\'%s\'"), lpszFieldName, lpszSymbol, lpszFieldValue);
			}break;
		case adUserDefined:			//_T("用户定义的变量 (DBTYPE_UDT). ");
		case adVarBinary:			//_T("二进制值. ");
		case adVariant:				//_T("自动变体型 (DBTYPE_VARIANT). ");
			break;
		case adCurrency:	//_T("货币值 (DBTYPE_CY).货币数字的小数点位置固定、小		
			break;
		case adDate:	//	_T("日期值 (DBTYPE_DATE).日期按双精度型数值来保存, 数\
			//				 字全部表示从 1899 年 12 月 30 开始的日期数.小数部分是\
			//				 一天当中的片段时间. ");			
			{
			}break;
		case adDBDate:	//_T("日期值 (yyyymmdd) (DBTYPE_DBDATE). ");			
			break;
		case adDBTime:	//_T("时间值 (hhmmss) (DBTYPE_DBTIME). ");			
			break;
		case adDBTimeStamp:	//_T("时间戳 (yyyymmddhhmmss 加 10 亿分之一的小数)(DBTYPE_DBTIMESTAMP). ");			
			break;
		case adDecimal:	//_T("具有固定精度和范围的精确数字值 (DBTYPE_DECIMAL). ");
			break;
		case adDouble:	//_T("双精度浮点值 (DBTYPE_R8). ");
			break;
		case adEmpty:	//_T("未指定值 (DBTYPE_EMPTY). ");
			break;
		case adError:			//_T("32 - 位错误代码 (DBTYPE_ERROR). ");
			break;
		case adGUID:			//_T("全局唯一的标识符 (GUID) (DBTYPE_GUID). ");
			break;
		case adIDispatch:		//_T("OLE 对象上 Idispatch 接口的指针 (DBTYPE_IDISPATCH). ");
		case adIUnknown:		//_T("OLE 对象上 IUnknown 接口的指针 (DBTYPE_IUNKNOWN).");
			break;
		case adInteger:			//_T("4 字节的带符号整型 (DBTYPE_I4). ");
			break;
		case adLongVarBinary:	// _T("长二进制值.");
			break;
		case adNumeric:			//_T("具有固定精度和范围的精确数字值 (DBTYPE_NUMERIC). ");
			break;
		case adSingle:			//_T("单精度浮点值 (DBTYPE_R4). ");
			break;
		case adSmallInt:		//_T("2 字节带符号整型 (DBTYPE_I2). ");
			break;
		case adTinyInt:			//_T("1 字节带符号整型 (DBTYPE_I1). ");
			break;
		case adUnsignedBigInt:	//_T("8 字节不带符号整型 (DBTYPE_UI8). ");
			break;
		case adUnsignedInt:		//_T("4 字节不带符号整型 (DBTYPE_UI4). ");
			break;
		case adUnsignedSmallInt:	//_T("2 字节不带符号整型 (DBTYPE_UI2). ");
			break;
		case adUnsignedTinyInt:		//_T("1 字节不带符号整型 (DBTYPE_UI1). ");
			break;
		default:
			{
			}break;
			//		case adVector:
			//		{
			//			lpFieldInfo->nFieldType = adve;
			//			lpFieldInfo->strTypeName= _T("");
			//			lpFieldInfo->strExplain = _T("与其他类型一起加入逻辑 OR 中, 指示数据是 DBVECTOR \
			//									  结构(由 OLE DB 定义).该结构含有元素的计数和其他类型 \
			//									  (DBTYPE_VECTOR) 数据的指针. ");
			//		}break;
		}
	}
	TRACE(_T(">>>>用AdoGetFormatWhere建立成的sql条件语句:%s\n"), _Where);
	return _Where;
}


//BOOL _SFX_EXT_CLASS InitAdoLibrary()
//{
//	CString m_ResFile;
//	LPTSTR lpszPath[MAX_PATH];// = _T("");
//	GetModuleFileName(NULL, (LPTSTR)lpszPath, MAX_PATH);
//	VERIFY(PathRemoveFileSpec((LPTSTR)lpszPath));
//
//	TRACE(_T("----%s\n"), lpszPath);
//
//	m_ResFile.Format(_T("%s\\sfxDB.lng"), lpszPath);
//	if (PathFileExistsUI(NULL, m_ResFile, _T("ado lib")))
//	{
//		return TRUE;
//	}
//
//	return FALSE;
//}

BOOL _SFX_EXT_CLASS RegAdoControl()
{
	HINSTANCE	hInstance;
	hInstance	= AfxGetInstanceHandle();
	WNDCLASS	wc;
	if (!(::GetClassInfo(hInstance, DBIMAGE_CLASS_NAME, &wc)))
	{
		wc.cbClsExtra	= 0;
		wc.cbWndExtra	= 0;
		wc.hbrBackground= (HBRUSH)COLOR_WINDOW;
		wc.hCursor		= AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		wc.hIcon		= NULL;
		wc.hInstance	= hInstance;
		wc.lpfnWndProc	= ::DefWindowProc;
		wc.lpszClassName= DBIMAGE_CLASS_NAME;
		wc.lpszMenuName = NULL;
		wc.style		= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

		if (!AfxRegisterClass(&wc))
		{
			AfxThrowResourceException();
			return FALSE;
		}
	}

	return TRUE;
}


void 
_SFX_EXT_CLASS 
adoShowComError(HWND hwnd,
				_com_error &comErroe)
{
	_bstr_t bstrSource(comErroe.Source());
	_bstr_t bstrDescription(comErroe.Description());
	CString _ErrorHint;

	// Print Com errors.
	_ErrorHint.Format(_T(" 错误!\n 代码:%08lx\n 代码含意:%s\n 来源:%s\n 描述:%s\n"),
		comErroe.Error(),
		comErroe.ErrorMessage(),
		(LPCTSTR)bstrSource,
		(LPCTSTR)bstrDescription);
	MessageBox(hwnd, _ErrorHint, _T("Com error"), MB_OK|MB_ICONERROR);
}

BOOL
WINAPI
DeleteRecordHint(
				 HWND hWndCtrl,
				 long lRecord
				 )
{
	CString _Hint;
	CString _Src;
	_Src = LoadIniStr(_T("IDS_DELETE_RECNO"), KEY_STRING, theApp.m_resFileName);
	_Hint.Format(_Src, lRecord);
	if (MessageBox(hWndCtrl, _Hint, _T(""), MB_OKCANCEL|MB_ICONQUESTION))
	{
		return TRUE;
	}
	return FALSE;
}

//////////////////////////////////////////////////////////////////////////
//
LONG
_SFX_EXT_CLASS
adoGetFieldSize(ADO::FieldPtr &field, long lCharSize)
{
	long _Rec = 0;
	switch(field->GetType())
	{
	case adArray:	//_T("全安数组");
	case adBigInt:  //_T("8 字节带符号的整数");
	case adBinary:	//_T("二进制");
	case adBoolean:	//_T("布尔型");

		//		case adByRef:
		//		{
		//			lpFieldInfo->nFieldType = ;adb
		//			lpFieldInfo->strTypeName= _T("");
		//			lpFieldInfo->strExplain = _T("与其他类型一起加入逻辑 OR 以指示该数据是其他类型数"	据的指针 (DBTYPE_BYREF). ");
		//		}break;
	case adLongVarChar:		//_T("长字符串值. ");
	case adLongVarWChar:	//_T("以空结尾的长字符串值. ");
		_Rec = 6*lCharSize;
		break;
	case adBSTR:	//_T("宽字符串");
	case adChar:	//_T("文本");
	case adUserDefined:			//_T("用户定义的变量 (DBTYPE_UDT). ");
	case adVarBinary:			//_T("二进制值. ");
	case adVarChar:				//_T("字符串值. ");
	case adVariant:				//_T("自动变体型 (DBTYPE_VARIANT). ");
	case adVarWChar:		//_T("以空结尾的 Unicode 字符串. ");
	case adWChar:			//_T("以空结尾的 Unicode 字符串 (DBTYPE_WSTR). ");			
		_Rec = field->GetDefinedSize() *lCharSize;
		break;
	case adCurrency:	//_T("货币值 (DBTYPE_CY).货币数字的小数点位置固定、小		
		_Rec = 6*lCharSize;
		break;
	case adDate:	//	_T("日期值 (DBTYPE_DATE).日期按双精度型数值来保存, 数\
		//				 字全部表示从 1899 年 12 月 30 开始的日期数.小数部分是\
		//				 一天当中的片段时间. ");			
		_Rec = 8*lCharSize;
		break;
	case adDBDate:	//_T("日期值 (yyyymmdd) (DBTYPE_DBDATE). ");			
		_Rec = 10*lCharSize;		
		break;
	case adDBTime:	//_T("时间值 (hhmmss) (DBTYPE_DBTIME). ");			
		_Rec = 8*lCharSize;					
		break;
	case adDBTimeStamp:	//_T("时间戳 (yyyymmddhhmmss 加 10 亿分之一的小数)(DBTYPE_DBTIMESTAMP). ");			
		_Rec = 8*lCharSize;					
		break;
	case adDecimal:	//_T("具有固定精度和范围的精确数字值 (DBTYPE_DECIMAL). ");
		_Rec = 8*lCharSize;		
		break;
	case adDouble:	//_T("双精度浮点值 (DBTYPE_R8). ");
		_Rec = 10*lCharSize;		
		break;
	case adEmpty:	//_T("未指定值 (DBTYPE_EMPTY). ");
		_Rec = 8*lCharSize;		
		break;
	case adError:			//_T("32 - 位错误代码 (DBTYPE_ERROR). ");
		_Rec = 8*lCharSize;		
		break;
	case adGUID:			//_T("全局唯一的标识符 (GUID) (DBTYPE_GUID). ");
		_Rec = 16*lCharSize;		
		break;
	case adIDispatch:		//_T("OLE 对象上 Idispatch 接口的指针 (DBTYPE_IDISPATCH). ");
	case adIUnknown:		//_T("OLE 对象上 IUnknown 接口的指针 (DBTYPE_IUNKNOWN).");
		_Rec = 15*lCharSize;
		break;
	case adInteger:			//_T("4 字节的带符号整型 (DBTYPE_I4). ");
		_Rec = 11*lCharSize;		
		break;
	case adLongVarBinary:	// _T("长二进制值.");
		_Rec = 10*lCharSize;		
		break;
	case adNumeric:			//_T("具有固定精度和范围的精确数字值 (DBTYPE_NUMERIC). ");
		_Rec = 10*lCharSize;
		break;
	case adSingle:			//_T("单精度浮点值 (DBTYPE_R4). ");
		_Rec = 8*lCharSize;		
		break;
	case adSmallInt:		//_T("2 字节带符号整型 (DBTYPE_I2). ");
		_Rec = 6*lCharSize;
		break;
	case adTinyInt:			//_T("1 字节带符号整型 (DBTYPE_I1). ");
		_Rec = 3*lCharSize;
		break;
	case adUnsignedBigInt:	//_T("8 字节不带符号整型 (DBTYPE_UI8). ");
		_Rec = 16*lCharSize;		
		break;
	case adUnsignedInt:		//_T("4 字节不带符号整型 (DBTYPE_UI4). ");
		_Rec = 8*lCharSize;		
		break;
	case adUnsignedSmallInt:	//_T("2 字节不带符号整型 (DBTYPE_UI2). ");
		_Rec = 4*lCharSize;
		break;
	case adUnsignedTinyInt:		//_T("1 字节不带符号整型 (DBTYPE_UI1). ");
		_Rec = 2*lCharSize;
		break;
	default:
		_Rec = 10*lCharSize;
		break;
		//		case adVector:
		//		{
		//			lpFieldInfo->nFieldType = adve;
		//			lpFieldInfo->strTypeName= _T("");
		//			lpFieldInfo->strExplain = _T("与其他类型一起加入逻辑 OR 中, 指示数据是 DBVECTOR \
		//									  结构(由 OLE DB 定义).该结构含有元素的计数和其他类型 \
		//									  (DBTYPE_VECTOR) 数据的指针. ");
		//		}break;
	}
	if (_Rec>(15*lCharSize)) 
	{
		_Rec = 15*lCharSize;
	}
	//_T("无法识别的字段类型。");
	return _Rec;
}