📄 cedbdlg.cpp
字号:
// CeDbDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CeDb.h"
#include "CeDbDlg.h"
#include "InputDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCeDbDlg dialog
CCeDbDlg::CCeDbDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCeDbDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCeDbDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCeDbDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCeDbDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCeDbDlg, CDialog)
//{{AFX_MSG_MAP(CCeDbDlg)
ON_BN_CLICKED(IDC_OPEN, OnOpen)
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_DELETE, OnDelete)
ON_BN_CLICKED(IDC_EDIT, OnEdit)
ON_BN_CLICKED(IDC_CLOSE, OnClose)
ON_BN_CLICKED(IDC_REFLASH, OnReflash)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCeDbDlg message handlers
BOOL CCeDbDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
//设置学生列表框标题
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_STU);
CRect rt;
pListCtrl->GetClientRect(&rt);
pListCtrl->InsertColumn(0,_T("编号"),LVCFMT_LEFT,rt.Width()*0.2);
pListCtrl->InsertColumn(1,_T("姓名"),LVCFMT_LEFT,rt.Width()*0.3);
pListCtrl->InsertColumn(2,_T("出生日期"),LVCFMT_LEFT,rt.Width()*0.3);
pListCtrl->InsertColumn(3,_T("身高"),LVCFMT_LEFT,rt.Width()*0.2);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCeDbDlg::OnOpen()
{
// TODO: Add your control notification handler code here
if(!CeMountDBVol(&m_cedb,DBFILENAME,OPEN_ALWAYS))
{
MessageBox(_T("挂载数据库失败"));
return;
}
//在这里要先把m_ceoid赋值为0才能打开数据库,不然是打不开数据库的。
m_ceoid = 0;
m_db = CeOpenDatabaseEx(&m_cedb,&m_ceoid,DBTABLENAME,NULL,CEDB_AUTOINCREMENT,NULL);
if(m_db == INVALID_HANDLE_VALUE)
{
//如果不存在就创建数据库
if(GetLastError() == ERROR_FILE_NOT_FOUND)
{
CEDBASEINFO ceDBInfo;//包含数据库对象信息的结构体
ceDBInfo.dwFlags = CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC;
wcscpy(ceDBInfo.szDbaseName,DBTABLENAME);
ceDBInfo.dwDbaseType = 0;
ceDBInfo.wNumSortOrder = 2 ; //排序字段数目
ceDBInfo.rgSortSpecs[0].propid = PID_NO;
ceDBInfo.rgSortSpecs[0].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小写无关
ceDBInfo.rgSortSpecs[1].propid = PID_NAME;
ceDBInfo.rgSortSpecs[1].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小写无关
m_ceoid = CeCreateDatabaseEx(&m_cedb,&ceDBInfo);
if(m_ceoid == NULL)
{
if(GetLastError() == ERROR_DUP_NAME)
{
MessageBox(_T("有一个无效的参数"));
}
AfxMessageBox(_T("创建数据库失败"));
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_cedb))
{
AfxMessageBox(_T("卸载数据库文件卷失败"));
}
return ;
}
//4、创建数据库后,应紧接着打开数据库
m_db = CeOpenDatabaseEx(&m_cedb,&m_ceoid,DBTABLENAME,NULL,CEDB_AUTOINCREMENT,NULL);
if (m_db == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("打开数据库失败"));
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_cedb))
{
AfxMessageBox(_T("卸载数据库文件卷失败"));
}
return ;
}
}
else
{
MessageBox(_T("打开数据库失败"));
}
return;
}
}
void CCeDbDlg::OnAdd()
{
// TODO: Add your control notification handler code here
CInputDlg mydlg;//DoModal出对话框的对象
if(mydlg.DoModal() == IDOK)
{
Student myStd;
wcscpy(myStd.szNo,mydlg.m_no);
wcscpy(myStd.szName,mydlg.m_name);
SYSTEMTIME myTime;
mydlg.m_birthday.GetAsSystemTime(myTime);//从系统得到在对话框设置的时间,GetAsSystemTime与GetSystemTime有区别,后者为系统显示时间
::SystemTimeToFileTime(&myTime,&(myStd.ftBirthday));//把系统时间转换为FileTime时间
myStd.iStature = mydlg.m_tall;
AddNewStudent(myStd);
}
//调用才刷新按钮的方法实现数据的更新
OnReflash();
}
void CCeDbDlg::OnDelete()
{
// TODO: Add your control notification handler code here
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_STU);
int itemIndex = pListCtrl->GetNextItem(-1,LVNI_SELECTED);
ASSERT(itemIndex !=-1);
DWORD dwIndex;
CEOID ceOid;
ceOid = CeSeekDatabase(m_db,CEDB_SEEK_BEGINNING,itemIndex,&dwIndex);
if(CeDeleteRecord(m_db,ceOid) ==0)
{
MessageBox(_T("删除失败"));
}
//调用才刷新按钮的方法实现数据的更新
OnReflash();
}
void CCeDbDlg::OnEdit()
{
// TODO: Add your control notification handler code here
Student rec_stu;
CEOID ceOid;
PBYTE pBuff;
WORD wProps;
DWORD dwRecSize;
PCEPROPVAL pRecord;
Student *pStudent;
//设置学生列表框标题
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_STU);
int iItemIndex = pListCtrl->GetNextItem(-1,LVNI_SELECTED);
ASSERT(iItemIndex !=-1);
DWORD dwIndex;
ceOid = CeSeekDatabase(m_db,CEDB_SEEK_BEGINNING,iItemIndex,&dwIndex);
ASSERT(ceOid !=0);
pBuff = 0;
//读取所有记录值
ceOid = CeReadRecordProps(m_db,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwRecSize);
ASSERT(ceOid != 0);
pRecord = (PCEPROPVAL)pBuff;
pStudent = new Student;
for (int i=0;i<wProps;i++)
{
switch(pRecord->propid)
{
case PID_NO:
{
wcscpy(pStudent->szNo,pRecord->val.lpwstr);
break;
}
case PID_NAME:
{
wcscpy(pStudent->szName,pRecord->val.lpwstr);
break;
}
case PID_BIRTHDAY:
{
pStudent->ftBirthday = pRecord->val.filetime;
break;
}
case PID_STATURE:
{
pStudent->iStature = pRecord->val.lVal;
break;
}
}
pRecord++;
}
LocalFree(pBuff);
CInputDlg inputDlg;
//同步编辑对话框输入框值
inputDlg.m_no = pStudent->szNo;
inputDlg.m_name = pStudent->szName;
SYSTEMTIME tmpTime;
FileTimeToSystemTime(&(pStudent->ftBirthday),&tmpTime);
inputDlg.m_birthday = tmpTime;
inputDlg.m_tall = pStudent->iStature;
delete pStudent;
if (inputDlg.DoModal() == IDOK)
{
//得到编号
wcscpy(rec_stu.szNo,LPCTSTR(inputDlg.m_no));
//得到姓名
wcscpy(rec_stu.szName,LPCTSTR(inputDlg.m_name));
//得到出生日期
SYSTEMTIME timeDest;
inputDlg.m_birthday.GetAsSystemTime(timeDest);
::SystemTimeToFileTime(&timeDest, &(rec_stu.ftBirthday));
//得到身高值
rec_stu.iStature = inputDlg.m_tall;
EditStudent(rec_stu,ceOid);
}
//编辑完成之后,调用刷新按钮单击方法
OnReflash();
}
void CCeDbDlg::OnClose()
{
// TODO: Add your control notification handler code here
if(!CloseHandle(m_db))
{
MessageBox(_T("关闭数据库失败"));
return;
}
if(!CeFlushDBVol(&m_cedb))
{
MessageBox(_T("缓存数据失败"));
return;
}
if(!CeUnmountDBVol(&m_cedb))
{
MessageBox(_T("卸载数据库失败"));
return;
}
}
//增加一条新记录
BOOL CCeDbDlg::AddNewStudent(Student stu)
{
CEOID myoid;
CEPROPVAL *pPropv;//包含数据库对象属性的结构体
pPropv = new CEPROPVAL[4];//指针必须new空间出来
//学生编号
memset(pPropv,0,sizeof(CEPROPVAL));//为指定的字符设置缓存区
pPropv->propid = PID_NO;//CEPROPVAL第一个参数为记录的属性列的ID
pPropv->val.lpwstr = stu.szNo;//第四个参数为记录值的联合体
//学生姓名
pPropv++;
memset(pPropv,0,sizeof(CEPROPVAL));
pPropv->propid = PID_NAME;
pPropv->val.lpwstr = stu.szName;
//学生出生日期
pPropv++;
memset(pPropv,0,sizeof(CEPROPVAL));
pPropv->propid = PID_BIRTHDAY;
pPropv->val.filetime = stu.ftBirthday;
//学生身高
pPropv++;
memset(pPropv,0,sizeof(CEPROPVAL));
pPropv->propid = PID_STATURE;
pPropv->val.iVal = stu.iStature;
pPropv = pPropv - 3;
myoid = CeWriteRecordProps(m_db,0,4,pPropv);//写数据库操作
if( myoid == 0 )
return false;
return true;
}
//从数据库中获得所有的数据,显示在列表试图中
void CCeDbDlg::OnReflash()
{
// TODO: Add your control notification handler code here
WORD wProps;//16位无符号整型
DWORD dwRecSize;//32位无符号整型
PBYTE pBuff;//pByte指向的元素类型BYTE的指针
CEOID ceoid;
PCEPROPVAL pRecord;
Student *pStu;
int RecondNum = GetRecordCount(&m_cedb,m_ceoid);
//设置学生列表框标题
CListCtrl * pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_STU);
pListCtrl->DeleteAllItems();
DWORD nIndex;
for(int i=0;i<RecondNum;i++)
{
ceoid = CeSeekDatabase(m_db,CEDB_SEEK_BEGINNING,i,&nIndex);//数据库中读取和写入记录之前,必须先查找到记录。使用 CeSeekDatabase 函数将数据库搜索指针移至要读取或写入的记录。
ASSERT(ceoid != 0);//ASSERT 如果满足条件就继续执行,不满足卡住
pBuff = 0;
//读取所有字段值
ceoid = CeReadRecordProps(m_db,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwRecSize);//读数据库操作
pRecord = (PCEPROPVAL)pBuff;
pStu = new Student;
for(int j=0;j<wProps;j++)
{
switch(pRecord->propid)
{
case PID_NO:
{
wcscpy(pStu->szNo,pRecord->val.lpwstr);
break;
}
case PID_NAME:
{
wcscpy(pStu->szName,pRecord->val.lpwstr);
break;
}
case PID_BIRTHDAY:
{
pStu->ftBirthday = pRecord->val.filetime;
break;
}
case PID_STATURE:
{
pStu->iStature = pRecord->val.lVal;
break;
}
}
pRecord++;
}
LocalFree(pBuff);//释放指针
//向列表中添加信息
pListCtrl->InsertItem(i,_T("Test"));
pListCtrl->SetItemText(i,0,pStu->szNo);
pListCtrl->SetItemText(i,1,pStu->szName);
//添加学生生日,此处需要做些转换
SYSTEMTIME systime;
FileTimeToSystemTime(&(pStu->ftBirthday),&systime);
TCHAR szBirthday[11];
swprintf(szBirthday,_T("%d-%d-%d"),systime.wYear,systime.wMonth,systime.wDay);
pListCtrl->SetItemText(i,2,szBirthday);
//添加学生身高,此处需要将数字转换成字符串
TCHAR szStature[5];
_itow(pStu->iStature,szStature,10);
pListCtrl->SetItemText(i,3,szStature);
delete pStu;
}
}
/*
函数说明:编辑记录
入口参数:stu : 学生数据库表结构
ceOid : 记录对象标识
出口参数:(无)
返 回 值:TRUE:编辑成功;FALSE:编辑失败
*/
BOOL CCeDbDlg::EditStudent(Student stu, CEOID ceOid)
{
CEOID tmpCeOid;
CEPROPVAL *pProps;
pProps = new CEPROPVAL[4];
//学生学号
memset(pProps,0,sizeof(CEPROPVAL));
pProps->propid = PID_NO;
pProps->val.lpwstr = stu.szNo;
//学生姓名
pProps++;
memset(pProps,0,sizeof(CEPROPVAL));
pProps->propid = PID_NAME ;
pProps->val.lpwstr = stu.szName;
//学生出生日期
pProps++;
memset(pProps,0,sizeof(CEPROPVAL));
pProps->propid = PID_BIRTHDAY;
pProps->val.filetime = stu.ftBirthday;
//学生身高
pProps++;
memset(pProps,0,sizeof(CEPROPVAL));
pProps->propid = PID_STATURE;
pProps->val.iVal = stu.iStature;
pProps = pProps -3 ;
tmpCeOid = CeWriteRecordProps(m_db,ceOid,4,pProps);//写数据库操作
if (tmpCeOid == 0)
{
return FALSE;
}
return TRUE;
}
int CCeDbDlg::GetRecordCount(CEGUID *pCeGuid, CEOID ceOid)
{
int iCount;
CEOIDINFO ceinfo;
if(!CeOidGetInfoEx(pCeGuid,ceOid,&ceinfo))//从数据库对象获得数据库信息
{
MessageBox(_T("获取信息失败"));
return -1;
}
iCount = ceinfo.infDatabase.wNumRecords;//返回数据库记录的数目
return iCount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -