📄 adooperation.cpp
字号:
// 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 + -