// DataBaseDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "DataBase.h"
#include "DataBaseDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CDataBaseDlg 对话框
CDataBaseDlg::CDataBaseDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDataBaseDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
ZeroMemory(&m_VolGUID,sizeof(m_VolGUID)); //存储数据库文件卷标识
m_hDB = INVALID_HANDLE_VALUE; //存储数据库句柄
m_ceOid = 0; //存储数据库对象标识
m_hSession = INVALID_HANDLE_VALUE; //会话句柄
}
void CDataBaseDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDataBaseDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
ON_BN_CLICKED(IDC_TJ,TjPresson)
ON_BN_CLICKED(IDC_DL,DlPresson)
ON_BN_CLICKED(IDC_XG,XgPresson)
ON_BN_CLICKED(IDC_CX,CxPresson)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CDataBaseDlg 消息处理程序
BOOL CDataBaseDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
#ifdef WIN32_PLATFORM_WFSP
if (!m_dlgCommandBar.Create(this) ||
!m_dlgCommandBar.InsertMenuBar(IDR_MAINFRAME))
{
TRACE0("未能创建 CommandBar/n");
return FALSE; // 未能创建
}
#endif // WIN32_PLATFORM_WFSP
//获取控件
CListCtrl* m_ListDisplay= (CListCtrl*)GetDlgItem(IDC_LIST1);
//LVS_EX_CHECKBOXES 表示添加CheckBox
//LVS_EX_FULLROWSELECT 表示选择整行
//LVS_EX_GRIDLINES 表示添加表格线
m_ListDisplay->SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//加载ID
m_ListDisplay->InsertColumn(0,_T("学号"),LVCFMT_LEFT,90);
//加载NAME
m_ListDisplay->InsertColumn(1,_T("姓名"),LVCFMT_LEFT,90);
//加入行
Cnt = 0;
m_ListDisplay->InsertItem (Cnt,_T(""));
m_ListDisplay->SetItemText(Cnt,0,_T("0001"));
m_ListDisplay->SetItemText(Cnt,1,_T("张三"));
//加入行
Cnt++;
m_ListDisplay->InsertItem (Cnt,_T(""));
m_ListDisplay->SetItemText(Cnt,0,_T("0002"));
m_ListDisplay->SetItemText(Cnt,1,_T("李四"));
//加入行
Cnt++;
m_ListDisplay->InsertItem (Cnt,_T(""));
m_ListDisplay->SetItemText(Cnt,0,_T("0003"));
m_ListDisplay->SetItemText(Cnt,1,_T("王老五"));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CDataBaseDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
DRA::RelayoutDialog(
AfxGetInstanceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_DATABASE_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_DATABASE_DIALOG));
}
#endif
BOOL CDataBaseDlg::DB_Create_Student( CEGUID * pCeGuid, const LPCTSTR strDBName)
{
//定义数据库基本信息
CEDBASEINFOEX DBInfo;
//填充DBInfo信息
memset(&DBInfo, 0, sizeof(CEDBASEINFOEX)) ;
DBInfo.wVersion = CEDBASEINFOEX_VERSION; //版本
DBInfo.dwFlags |= CEDB_VALIDDBFLAGS | CEDB_VALIDNAME | CEDB_VALIDSORTSPEC; //标识
DBInfo.wNumSortOrder = 2; //排序字段数目
wcscpy(DBInfo.szDbaseName , DBTABLENAME); //数据库名
//定义第1个排序方式
DBInfo.rgSortSpecs[0].wVersion = SORTORDERSPECEX_VERSION;
DBInfo.rgSortSpecs[0].wNumProps = 1;
DBInfo.rgSortSpecs[0].wKeyFlags = 0;//CEDB_SORT_UNIQUE;
DBInfo.rgSortSpecs[0].rgPropID[0] = PID_NO; //学生编号
DBInfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_DESCENDING;
//定义第2个排序方式
DBInfo.rgSortSpecs[1].wVersion = SORTORDERSPECEX_VERSION;
DBInfo.rgSortSpecs[1].wNumProps = 1;
DBInfo.rgSortSpecs[1].wKeyFlags = 0;
DBInfo.rgSortSpecs[1].rgPropID[0] = PID_NAME; //学生姓名
DBInfo.rgSortSpecs[1].rgdwFlags[0] = CEDB_SORT_DESCENDING;
//设置字段属性
CEPROPSPEC dbPropInfo[2];
//学生编号
dbPropInfo[0].wVersion = 1;
dbPropInfo[0].propid = PID_NO;
dbPropInfo[0].pwszPropName = L"学号";
dbPropInfo[0].cchPropName = wcslen(dbPropInfo[0].pwszPropName);
dbPropInfo[0].dwFlags = 0;
//学生姓名
dbPropInfo[1].wVersion = 1;
dbPropInfo[1].propid = PID_NAME;
dbPropInfo[1].pwszPropName = L"姓名";
dbPropInfo[1].cchPropName = wcslen(dbPropInfo[1].pwszPropName);
dbPropInfo[1].dwFlags = 0;
//创建数据库
m_ceOid = CeCreateDatabaseWithProps(pCeGuid, &DBInfo, 2, dbPropInfo);
if (m_ceOid == 0)
{
TRACE(L"创建数据库失败,The Error Code =%d /n",GetLastError());
return FALSE;
}
return TRUE;
}
//打开数据库
BOOL CDataBaseDlg::DB_Open_Student(const LPCTSTR strVolumeName,const LPCTSTR strDBName)
{
BOOL bResult = FALSE;
DWORD dwErrorCode = 0;
//定义排序方式
SORTORDERSPECEX rgSortSpecs;
rgSortSpecs.wVersion = SORTORDERSPECEX_VERSION;
rgSortSpecs.wNumProps = 1;
rgSortSpecs.wKeyFlags = CEDB_SORT_UNIQUE;
rgSortSpecs.rgPropID[0] = PID_NO;
rgSortSpecs.rgdwFlags[0] = CEDB_SORT_DESCENDING;
//rgSortSpecs.rgPropID[1] = PID_NAME;
//rgSortSpecs.rgdwFlags[1] = CEDB_SORT_DESCENDING;
//1、挂载数据库卷,如果存在则打开,不存在,就新建一个
if (!CeMountDBVolEx(&m_VolGUID,DBFILENAME,NULL,OPEN_ALWAYS))
{
TRACE(_T("打开或新建数据卷失败 /n"));
return FALSE;
}
//2,创建会话句柄
m_hSession = CeCreateSession(&m_VolGUID);
//3、接着打开数据库
m_hDB = CeOpenDatabaseInSession( m_hSession,
&m_VolGUID,
&m_ceOid,
DBTABLENAME,
&rgSortSpecs,
0,//CEDB_AUTOINCREMENT,
NULL) ;
if (m_hDB == INVALID_HANDLE_VALUE)
{
dwErrorCode = GetLastError();
//4、如果数据库不存在,就新建之
if ( dwErrorCode== ERROR_FILE_NOT_FOUND)
{
//创建新数据库
if (!DB_Create_Student(&m_VolGUID,DBTABLENAME))
{
TRACE(L"打开数据库失败/n");
goto error;
}
//5、创建数据库后,应紧接着打开数据库
m_hDB = CeOpenDatabaseInSession( m_hSession,
&m_VolGUID,
&m_ceOid,
DBTABLENAME,
&rgSortSpecs,
0,//CEDB_AUTOINCREMENT,
NULL) ;
if (m_hDB == INVALID_HANDLE_VALUE)
{
TRACE(L"打开数据库失败/n");
goto error;
}
}
else
{
TRACE(L"打开数据库失败/n");
goto error;
}
}
return TRUE;
error:
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_VolGUID))
{
TRACE(_T("卸载数据库文件卷失败"));
}
return FALSE;
}
//关闭数据库
BOOL CDataBaseDlg::DB_Close_Student()
{
//1、关闭数据库
if (m_hDB != INVALID_HANDLE_VALUE )
{
if (!CloseHandle(m_hDB))
{
TRACE(L"关闭数据库失败/n");
return FALSE;
}
}
//2、将数据库卷的数据缓冲到永久存储介质上
if ((m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0))
{
if (!CeFlushDBVol(&m_VolGUID))
{
TRACE(L"缓冲介质失败/n");
return FALSE;
}
}
//3 、关闭回话对象
if (m_hSession != INVALID_HANDLE_VALUE )
{
if (!CloseHandle(m_hSession))
{
TRACE(L"关闭回话对象失败/n");
return FALSE;
}
}
//4、卸载数据库卷
if ((m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0)
|| (m_VolGUID.Data1 != 0))
{
if (!CeUnmountDBVol(&m_VolGUID))
{
TRACE(L"卸载数据库文件卷失败/n");
return FALSE ;
}
}
return TRUE;
}
//得到记录个数
int CDataBaseDlg::GetRecordCount(CEGUID *pCeGuid,CEOID ceOid)
{
int iCount;
CEOIDINFOEX oidinfo;
oidinfo.wVersion = CEOIDINFOEX_VERSION;
//获取数据库信息
if (!CeOidGetInfoEx2(pCeGuid,ceOid,&oidinfo))
{
TRACE(L"获取信息失败/n");
return -1;
}
//判断oidinfo.wObjType是否是数据库类型
if (oidinfo.wObjType != OBJTYPE_DATABASE)
{
return -1;
}
//得到记录数
iCount = oidinfo.infDatabase.dwNumRecords;
return iCount;
}
//查询所有记录
BOOL CDataBaseDlg::QueryAllRecords(DWORD *pRecordCount,student **pRecStudent)
{
CEOID ceOid = 0;
WORD wProps = 0;
DWORD dwRecSize = 0;
PBYTE pBuff = 0;
DWORD dwIndex = 0;
PCEPROPVAL pRecord = NULL;
DWORD dwRecordCount = 0;
//1,打开学生数据库
if (!DB_Open_Student())
{
//打开学生数据库失败
return FALSE;
}
//得到数据库记录数
dwRecordCount = GetRecordCount(&m_VolGUID,m_ceOid);
//返回记录数
*pRecordCount = dwRecordCount;
//如果记录数为0,返回
if (dwRecordCount ==0)
{
//关闭数据库
DB_Close_Student();
return TRUE;
}
//分配记录数组
*pRecStudent = new student[dwRecordCount];
//置0
ZeroMemory(*pRecStudent,sizeof(student)*dwRecordCount);
//读取所有记录
for (UINT i=0;i<dwRecordCount;i++)
{
//移动记录指针
ceOid = CeSeekDatabaseEx(m_hDB,CEDB_SEEK_BEGINNING,i,0,&dwIndex);
ASSERT(ceOid !=0);
pBuff = 0;
//读取所有字段值
ceOid = CeReadRecordPropsEx(m_hDB,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwRecSize,NULL);
ASSERT(ceOid != 0);
pRecord = (PCEPROPVAL)pBuff;
//读取所有字段值
for (int j=0;j<wProps;j++)
{
switch((pRecord+j)->propid)
{
//学生编号
case PID_NO:
{
wcscpy((*pRecStudent+i)->szNO,(pRecord+j)->val.lpwstr);
break;
}
//学生姓名
case PID_NAME:
{
wcscpy((*pRecStudent+i)->szName,(pRecord+j)->val.lpwstr);
break;
}
default:
{
}
}
}
//释放内存
LocalFree(pBuff);
}
//关闭数据库
DB_Close_Student();
return TRUE;
}
//删除记录
BOOL CDataBaseDlg::DeleteStudent(LPCTSTR strNo,LPCTSTR strName)
{
//定义学生编号查找字段属性
CEPROPVAL seekPropVal; //
CEOID ceOid;
DWORD dwIndex = 0;
//1,打开学生数据库
if (!DB_Open_Student())
{
//打开学生数据库失败
return FALSE;
}
//赋值学生编号查找字段属性
ZeroMemory(&seekPropVal,sizeof(seekPropVal));
if(*strNo != 0)
{
seekPropVal.propid = PID_NO;
seekPropVal.val.lpwstr = (LPWSTR)strNo;
}
else
{
seekPropVal.propid = PID_NAME;
seekPropVal.val.lpwstr = (LPWSTR)strName;
}
//根据学生编号,查找对应要删除的记录
ceOid = CeSeekDatabaseEx(m_hDB,CEDB_SEEK_VALUEFIRSTEQUAL,(DWORD)&seekPropVal,1,&dwIndex);
if (ceOid == 0)
{
TRACE(L"未查找到此记录/n");
goto error;
}
//删除当前记录
if (!CeDeleteRecord(m_hDB,ceOid))
{
TRACE(L"删除记录失败/n");
goto error;
}
return TRUE;
error:
//关闭数据库
DB_Close_Student();
return FALSE;
}
//刷新记录
void CDataBaseDlg::OnBnClickedBtnrefresh()
{
//定义学生记录对象
student *pRecStudent = NULL;
DWORD iRecCount = 0;
//设置学生列表框标题
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1);
//先删除全部显示
pListCtrl->DeleteAllItems();
//查询所有学生记录
if (QueryAllRecords(&iRecCount,&pRecStudent))
{
//显示记录
for (UINT i=0;i< iRecCount ; i++)
{
pListCtrl->InsertItem(i,L"");
//添加学生编号
pListCtrl->SetItemText(i,0,(pRecStudent+i)->szNO);
//添加学生姓名
pListCtrl->SetItemText(i,1,(pRecStudent+i)->szName);
}
}
//释放学生记录数组内存
delete[] pRecStudent;
pRecStudent = NULL;
}
//添加数据库
void CDataBaseDlg::TjPresson()
{
//定义学生数据库对象
CEOID ceOid;
//定义字段属性
CEPROPVAL pProps[2];
DWORD dwErrorCode = 0;
DWORD dwWritten = 0;
//1,打开学生数据库
if (!DB_Open_Student())
{
//打开学生数据库失败
return;
}
//给字段属性赋值
ZeroMemory(&pProps[0],sizeof(CEPROPVAL)*2);
CEdit* Tjxh = (CEdit*)GetDlgItem(IDC_TXH);
CEdit* Tjxm = (CEdit*)GetDlgItem(IDC_TXM);
CStringW strxh;
CStringW strxm;
Tjxh->GetWindowText(strxh);
Tjxm->GetWindowText(strxm);
//学生学号
pProps[0].propid = PID_NO;
pProps[0].val.lpwstr = strxh.GetBuffer();
pProps[0].wFlags = 0;
//学生姓名
pProps[1].propid = PID_NAME ;
pProps[1].val.lpwstr = strxm.GetBuffer();
pProps[1].wFlags = 0;
//写入记录
ceOid = CeWriteRecordProps(m_hDB,0,2,pProps);
if (ceOid == 0)
{
dwErrorCode = GetLastError();
//如果 dwErrorCode = 183, 表示学生编号重复
if (dwErrorCode == ERROR_ALREADY_EXISTS)
{
AfxMessageBox(L"学生编号重复/n");
}
else
{
AfxMessageBox(L"写入记录失败 , Error Code = %d /n",dwErrorCode);
}
}
//更新记录
OnBnClickedBtnrefresh();
//关闭数据库
DB_Close_Student();
}
//删除数据库
void CDataBaseDlg::DlPresson()
{
//设置学生列表框标题
CString strNo;
CString strName;
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1);
int iItemIndex = pListCtrl->GetNextItem(-1,LVNI_SELECTED);
if(iItemIndex == -1){
CEdit* Tjxh = (CEdit*)GetDlgItem(IDC_DXH);
CEdit* Tjxm = (CEdit*)GetDlgItem(IDC_DXM);
Tjxh->GetWindowTextW(strNo);
Tjxm->GetWindowTextW(strName);
}
else{
//得到学生编号
strNo = pListCtrl->GetItemText(iItemIndex,0);
}
//删除学生记录
if (!DeleteStudent(strNo,strName))
{
AfxMessageBox(L"删除记录失败");
}
//更新记录
OnBnClickedBtnrefresh();
//关闭数据库
DB_Close_Student();
}
void CDataBaseDlg::XgPresson()
{
//修改行
CListCtrl* m_ListDisplay = (CListCtrl*)GetDlgItem(IDC_LIST1);
CEdit* Tjxh = (CEdit*)GetDlgItem(IDC_XXH);
CEdit* Tjxm = (CEdit*)GetDlgItem(IDC_XXM);
CStringW strxh;
CStringW strxm;
Tjxh->GetWindowTextW(strxh);
Tjxm->GetWindowTextW(strxm);
if((strxh == "")&&(strxm == ""))
{
AfxMessageBox(_T("输入信息不完整,请重新输入!!"));
return;
}
if(AfxMessageBox(_T("修改"),MB_YESNO)==IDYES)
{
for(UINT i = 0; i<Cnt; i++)
{
if((strxh == m_ListDisplay->GetItemText(i,0))||(strxm == m_ListDisplay->GetItemText(i,1)))
{
m_ListDisplay->SetItemText(i,0,strxh);
m_ListDisplay->SetItemText(i,1,strxm);
}
}
}
}
void CDataBaseDlg::CxPresson()
{
//更新记录
OnBnClickedBtnrefresh();
//关闭数据库
DB_Close_Student();
}