⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adooperation.cpp

📁 VC++和ACCESS使用ADO连接
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ADOOperation.cpp: implementation of the CADOOperation class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MinistryPerson.h"
#include "ADOOperation.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#include "msword9.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

const DWORD CADOOperation::ADO_TYPE_STRING		  = 100;
const DWORD CADOOperation::ADO_TYPE_BITMAP_FILE	  = 101;
const DWORD CADOOperation::ADO_TYPE_INT			  = 102;
const DWORD CADOOperation::ADO_TYPE_FLOAT		  = 103;
const DWORD CADOOperation::ADO_TYPE_DATE		  = 104;
const DWORD CADOOperation::ADO_TYPE_BITMAP_HANDLE = 105;
const DWORD CADOOperation::ADO_TYPE_TEXT		  = 106;

CADOOperation::CADOOperation()
{
	try
	{
		m_pConnection.CreateInstance(__uuidof(Connection));    // 创建连接实例
		m_pConnection->Open(_bstr_t(Provider), "", "", adModeUnknown);
	}
	catch (_com_error e)
	{
		AfxMessageBox(e.Description(), MB_OK);
		exit(0);
	}

	m_pRecordset.CreateInstance(__uuidof(Recordset));
	m_CurrentRecord = -1;
	m_hDC = NULL;
}

CADOOperation::~CADOOperation()
{
	m_pConnection->Close();
}

/*********************************************************************
函数说明:	  显示错误信息而定义的函数
函数参数:	  e.Description
*********************************************************************/
void CADOOperation::ShowError(_bstr_t error)
{
	::MessageBox(NULL, error, "ADO错误", MB_OK | MB_ICONWARNING);
}

/*********************************************************************
函数说明:	  打开名为 strNmae 数据表
函数参数:	  表名
*********************************************************************/
BOOL CADOOperation::OpenTable(CString strName)
{
	ASSERT(!strName.IsEmpty());	// 表名不能为空
	CString strSQL;	
	strSQL.Format("select * from %s", strName);	// 格式化要打开表的SQL语句
	try
	{
		// 打开记录集
		m_pRecordset->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(), 
							adOpenDynamic, adLockOptimistic, adCmdText);	
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}

	return TRUE;
}

/*********************************************************************
函数说明:	  关闭打开的数据表
*********************************************************************/
BOOL CADOOperation::CloseTable()
{
	try
	{
		if (adStateOpen == m_pRecordset->GetState())	// 判断当前的记录集状态
		{
			m_pRecordset->Close();
		}
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}

	return TRUE;
}

/*********************************************************************
函数说明:	  执行SQL语句,并返回记录集
函数参数:	  所要执行的SQL语句
*********************************************************************/
BOOL CADOOperation::OpenRecordset(CString strSQL)
{
	ASSERT(!strSQL.IsEmpty());    // SQL语句不能为空
	try
	{
		// 执行SQL得到记录集
		m_pRecordset->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(),
							adOpenDynamic, adLockOptimistic, adCmdText);	
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}

	return TRUE;
}

/*********************************************************************
函数说明:	  把 Variable 所指的变量以 dwType 的类型存入当前的 sreField 域里
函数参数:	  字段名 、 字段类型 、 指向字段值的指针
*********************************************************************/
BOOL CADOOperation::SetItemContent(CString strField, DWORD dwTpye, const void *Variable)
{
	ASSERT(!strField.IsEmpty());	// 字段值不能为空
	ASSERT(NULL != Variable);		// 指针不能为空

	try
	{
		switch (dwTpye)
		{
		case ADO_TYPE_STRING:			// 字符串类型
			{
				// 把数据转换为字符指针后写到数据库中
				m_pRecordset->PutCollect(_bstr_t(strField), _bstr_t(*(CString*)(Variable)));
			}			
			break;
		case ADO_TYPE_BITMAP_FILE:		// 位图文件类型
			{
				CString *lpstr = (CString*)Variable;		// 得到位图文件名字符串指针				
				CFile   file(*lpstr, CFile::modeRead);		// 打开位图文件
				DWORD   dwFileSize = file.GetLength() + 1;	// 得到文件长度
				CHAR	*bitBuffer = new CHAR[dwFileSize];	// 新建一个缓冲区
				file.ReadHuge(bitBuffer, dwFileSize);		// 读出位图文件的信息
				file.Close();								// 关闭文件

				VARIANT bitData = {0};
				bitData.vt = VT_ARRAY | VT_UI1;							// 设置数据类型为数组类型				
				SAFEARRAY *pSafeArray;
				SAFEARRAYBOUND arrayBound[1];
				arrayBound[0].cElements = dwFileSize;					// 设置数组大小
				arrayBound[0].lLbound   = 0;							// 起始边界为0
				pSafeArray = ::SafeArrayCreate(VT_UI1, 1, arrayBound);	// 得到数组指针
				for (DWORD i = 0; i < dwFileSize - 1; i++)
				{
					::SafeArrayPutElement(pSafeArray, (long*)&i, bitBuffer++);	// 为数组填充元素
				}
				bitData.parray = pSafeArray;

				// 把数据写入到数据库中
				m_pRecordset->GetFields()->GetItem(_bstr_t(strField))->AppendChunk(bitData);
			}
			break;
		case ADO_TYPE_TEXT:		// 文件类型
			{
				CString *lpstr = (CString*)Variable;	// 把指针转换为字符串指针
				VARIANT data;
				SAFEARRAY *pSafeArray;
				SAFEARRAYBOUND arrayBound;
				CHAR *buf;

				data.vt = VT_ARRAY | VT_UI1;								// 设置类型为数组类型
				arrayBound.cElements = lpstr->GetLength();					// 设置元素个数
				arrayBound.lLbound = 0;										// 起始边界为0
				pSafeArray = ::SafeArrayCreate(VT_UI1, 1, &arrayBound);		// 创建一个数组
				buf = lpstr->GetBuffer(0);
				for (DWORD i = 0; i < arrayBound.cElements; i++)
				{
					::SafeArrayPutElement(pSafeArray, (long*)&i, buf++);	// 填充元素
				}
				data.parray = pSafeArray;

				m_pRecordset->GetFields()->GetItem(_bstr_t(strField))->AppendChunk(data);	// 写入数据库 
			}
			break;
		case ADO_TYPE_DATE:		// 日期类型
			{
				CString str;
				LPSYSTEMTIME lpSystemTime = (LPSYSTEMTIME)Variable;			// 把数据类型转换为日期型
				// 以字符串的形式存储日期型数据
				str.Format("%d-%d-%d", lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay);
				m_pRecordset->PutCollect(_bstr_t(strField), _bstr_t(str));	// 保存数据
			}
			break;
		case ADO_TYPE_INT:		// 整型
			{
				CString str;
				str.Format("%d", *(int*)Variable);							// 以字符串的形式存在
				m_pRecordset->PutCollect(_bstr_t(strField), _bstr_t(str));	// 保存数据
			}
			break;
		case ADO_TYPE_FLOAT:	// 浮点类型 
			{
				CString str;
				str.Format("%.2f", *(float*)Variable);						// 转换为字符串
				m_pRecordset->PutCollect(_bstr_t(strField), _bstr_t(str));	// 存入数据库
			}
			break;
		default:
			return FALSE;
		}
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}

	return TRUE;
}

/*********************************************************************
函数说明:	  得到当前记录的序列号
函数参数:	  记录的序列号 dwIndex
*********************************************************************/
_variant_t CADOOperation::GetSubItemIndex(DWORD dwIndex)
{
	_variant_t var;
	try
	{
		var = m_pRecordset->GetCollect(_variant_t((long)dwIndex));		// 得到数据
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return var;
	}

	return var;
}

/*********************************************************************
函数说明:	  读取当前记录的 field 域的数据
函数参数:	  field 域的数据
*********************************************************************/
_variant_t CADOOperation::GetSubItemField(CString strField)
{
	_variant_t var;
	try
	{
		var = m_pRecordset->GetCollect(_variant_t((_bstr_t)strField));		// 得到field 域的值
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return var;
	}

	return var;
}

/*********************************************************************
函数说明:	  把 _variant_t 转换为指定的类型
函数参数:	  
*********************************************************************/
BOOL CADOOperation::ChangeTypeTo(_variant_t From, DWORD Type, void *pTo, long Add)
{
	ASSERT(NULL != pTo);	// 参数 NULL 不能为空
	switch (Type)
	{
	case ADO_TYPE_DATE:		// 转换日期类型
		{
			if (From.vt == VT_NULL)
			{
				return FALSE;
			}
			
			LPSYSTEMTIME SysTime = (LPSYSTEMTIME)pTo;	// 转换为 LPSYSTEMTIME 类型
			int nPointYM;
			int nPointMD;
			CString str = (CHAR*)_bstr_t(From);			// 把 _variant_t 转换为字符串
			CString strData, strMonth, strYear;
			
			// 得到对应的年月日信息
			nPointYM = str.Find("-", 0);
			strYear  = str.Left(nPointYM);
			nPointMD = str.Find("-", nPointYM + 1);
			strData  = str.Right(str.GetLength() - nPointMD - 1);
			strMonth = str.Mid(nPointYM + 1, nPointMD - nPointYM - 1);
			SysTime->wDay   = atoi(strData.GetBuffer(0));
			SysTime->wMonth = atoi(strMonth.GetBuffer(0));
			SysTime->wYear  = atoi(strYear.GetBuffer(0));
		}
		break;
	case ADO_TYPE_BITMAP_HANDLE:	// 读取位图,并以句柄的形式返回
		{
			if (NULL == From.vt)
			{
				return FALSE;
			}

			if (Add > 0)
			{
				CHAR *pBuffer;
				if ((pBuffer = new CHAR[Add]) != NULL)		// 新建一个缓冲区用于保存位图信息
				{
					if (From.vt == (VT_ARRAY | VT_UI1))		// 判断数据类型
					{
						CHAR *pBuf;
						::SafeArrayAccessData(From.parray, (void**)&pBuf);
						::memcpy(pBuffer, pBuf, Add);
						::SafeArrayUnaccessData(From.parray);

						CHAR  *pDib;
						LPVOID lpDibBits;
						BITMAPFILEHEADER &bmfHeader = *(BITMAPFILEHEADER*)pBuffer;
						DWORD bmfHeaderLen = sizeof(bmfHeader);		// 获取文件头大小
						if (bmfHeader.bfType != (*(DWORD*)"BM"))	// 测试是否是位图文件
						{
							return TRUE;
						}

						pDib = pBuffer + bmfHeaderLen;
						BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)pDib;
						BITMAPINFO &bmInfo = *(LPBITMAPINFO)pDib;
						lpDibBits = pBuffer + ((BITMAPFILEHEADER*)pBuffer)->bfOffBits;

						// 根据数据创建一个DIB位图
						*(HBITMAP*)pTo = ::CreateDIBitmap(m_hDC, &bmiHeader, CBM_INIT, lpDibBits,
															&bmInfo, DIB_RGB_COLORS);
					}
				}
			}
		}
		break;
	case ADO_TYPE_TEXT:
		{
			CString *pStr = (CString*)pTo;
			*pStr = (CHAR*)_bstr_t(From);
		}
		break;
	case ADO_TYPE_FLOAT:
		{
			if (From.vt == VT_NULL)
			{
				(*(double*)pTo) = 0;
				break;
			}
			(*(double*)pTo) = (double)From;
		}
		break;
	case ADO_TYPE_INT:
		{
			if (From.vt == VT_NULL)
			{
				(*(long*)pTo) = 0;
				break;
			}
			(*(long*)pTo) = (long)From;
		}
		break;
	case ADO_TYPE_STRING:
		{
			*(CString*)pTo = (CHAR*)_bstr_t(From);
		}
		break;
	default:
		return FALSE;
	}

	return TRUE;
}

/*********************************************************************
函数说明:	  删除序号为 dwIndex的记录
函数参数:	  序号
*********************************************************************/
BOOL CADOOperation::DeleteItem(DWORD dwIndex)
{
	ASSERT(dwIndex >= 0);
	try
	{
		m_pRecordset->Move(dwIndex);			// 移动到指定位置
		m_pRecordset->Delete(adAffectCurrent);	// 删除当前位置的记录
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}
	
	return TRUE;
}

/*********************************************************************
函数说明:	  得到当前记录的 dwField 域的值并以 dwType 类型保存到 Variable指针里
函数参数:	  域序号, 需要读取的数据的类型, 指向需要返回数据的指针
*********************************************************************/
BOOL CADOOperation::GetItemContentDw(DWORD dwField, DWORD dwType, void *Variable)
{
	ASSERT(dwType != ADO_TYPE_BITMAP_HANDLE);	// 不处理位图控制块
	_variant_t variant;
	BOOL bRet = TRUE;
	try
	{
		variant = m_pRecordset->GetCollect(_variant_t((long)dwField));	// 读取数据值
		bRet = ChangeTypeTo(variant, dwType, Variable, 0);				// 转换为指定的类型
	}
	catch (_com_error e)
	{
		ShowError(e.Description());
		return FALSE;
	}

	return bRet;
}

/*********************************************************************
函数说明:	   在指定的窗口以列表的形式显示已经打开的数据表
函数参数:	   需要显示的域 、 域的个数 、 显示列表的窗口
*********************************************************************/
BOOL CADOOperation::ShowADOView(CString strFields[], int nLen, CADOView *view)
{
	int i = 0;
	CString *str = new CString[nLen];

	view->DeleteAllRows();				// 删除所在现存列
	if (m_pRecordset->adoEOF)			// 判断当前是否有记录,没有则返回
	{
		return TRUE;
	}

	do 
	{
		for (int j = 0; j < nLen; j++)
		{
			str[j] = (CHAR*)_bstr_t(m_pRecordset->GetCollect(_bstr_t(strFields[j])));	// 得到指定域的记录
		}
		view->SetRow(i, str, nLen);		// 显示到对应的行中
		m_pRecordset->MoveNext();		// 移到下一条记录
		i++;
	} 
	while (!m_pRecordset->adoEOF);

	delete []str;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -