最近遇到烦心事,一个傻逼领导让我在他电脑上现场演示一步步编写一个数据库操作程序。
我好像也没说熟悉数据库编程,虽说早些年有编写很多应用实例。一直都搞硬件,非标设备,具体代码早就忘得一干二净,只初步有个映像。
领导也是个初次使用vc的新手,老鸟菜鸟,字里行间就能知晓。
电脑安装VS2010,VS2015搞的新项目都不能创建,头文件都不能识别,新添加按钮ID也识别不了。
脾气硬压着,说不会也真不行,毕竟人家官位,权力在那摆着。
现场也只能在搞问题,这里按人家的要求,回家后彻夜搞出了个DEMO,也是参考以往写的实例。
界面如下:
软件操作的文件为事先用ACCESS创建的数据库文件alarminfo.mdb。
内有表格test,字段几个,如下图。
例程通过界面按钮1,2,3可以生成数据,添加位图文件,并保存到数据库文件中。
例程主要是想实现通过现场PLC等硬件触发报警事件,记录报警数据与现场图片。
后期 用于保存到其他系统或显示于现场。
相对还是很简单的一个功能,很少用到数据库编程,这个实例就当复习复习,过不了多久肯定又忘光。
例程下载地址:
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
下面记录下编写的程序的大概过程。
导入数据库文件。
在stdafx.h添加代码#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
导入与生成数据库操作所需文件。
2.在APP类中添加变量
public:
_ConnectionPtr m_pConnection;
InitInstance函数中初始化。
- AfxOleInit();
- m_pConnection.CreateInstance("ADODB.Connection");
- /******************连接数据库********************/
- try
- {
- m_pConnection->ConnectionTimeout = 8;
- //连接SQL SERVER
- //m_pConnection->Open("Driver=SQL Server;Database=test;Server=127.0.0.1;UID=sa;PWD=;","","",adModeUnknown);
- //连接ACCESS2000
- m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=alarminfo.mdb","","",adModeUnknown);
- }
- catch(_com_error e)///捕捉异常
- {
- AfxMessageBox("数据库连接失败!");
- return FALSE;
- }
复制代码 ExitInstance中释放资源,(可选)
- int CMy123App::ExitInstance()
- {
- if(m_pConnection->State)
- m_pConnection->Close();
- m_pConnection.Release();
- return CWinApp::ExitInstance();
- }
复制代码 3.在对话框类中添加成员变量与函数
- public:
- _RecordsetPtr m_pRecordset; //记录集对象
- HBITMAP m_hPhotoBitmap; //位图句柄
- BOOL m_bModify; //是否处于修改状态
- BOOL m_bNewUser; //是否处于增加记录状态
- char *m_pBMPBuffer; //内存数据
- DWORD m_nFileLen;
- //<>
- void ReadData();
- void DestroyPhoto();
- HBITMAP BufferToHBITMAP();
- void DrawPhoto(int x,int y,CDC* pDC);
- BOOL FirstRecord();
- BOOL LastRecord();
- BOOL LoadBMPFile(const char* pBMPPathname);
- void UpdateGrid();
复制代码 以及界面控件的添加与布局,具体函数的定义与控件的ID可以下载实例查看。
OnInitDialog函数中记得初始化相关控件与变量。
- CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST1);
- long dwStyle = pList->GetExtendedStyle();
- dwStyle |= LVS_EX_FULLROWSELECT;
- dwStyle |= LVS_EX_GRIDLINES; //网格线(只适用与报表风格的listctrl)
- pList->SetExtendedStyle(dwStyle);
- pList->InsertColumn(0,"故障时间",LVCFMT_CENTER,250);
- pList->InsertColumn(1,"故障数据1",LVCFMT_CENTER,200);
- pList->InsertColumn(2,"故障数据2",LVCFMT_CENTER,200);
- //<>
- srand((unsigned)time(NULL));/*播种子*/
- m_bModify = FALSE;
- m_hPhotoBitmap = NULL;
- m_pBMPBuffer = NULL;
- m_bNewUser = FALSE;
- //
- m_pRecordset.CreateInstance("ADODB.Recordset");
- HRESULT hr = m_pRecordset->Open("SELECT * FROM test",
- _variant_t((IDispatch *)theApp.m_pConnection,true),
- adOpenDynamic,adLockPessimistic,adCmdText);
- if(SUCCEEDED(hr))
- {
- ReadData();
- }
- UpdateGrid();
复制代码 4.接头就是界面元件响应函数的添加与实现。
选择照片:
- void CMy123Dlg::OnBnClickedButton3()
- {
- static char BASED_CODE szFilter[] = "BMP Files (*.bmp)|*.bmp||";
- CFileDialog dlg(TRUE,"BMP",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
- if(dlg.DoModal() == IDOK)
- {
- CString pathname = dlg.GetPathName();
- DestroyPhoto();
- LoadBMPFile(pathname);
- m_hPhotoBitmap = BufferToHBITMAP();
- m_bModify = TRUE;
- Invalidate();
- }
- }
复制代码 生成数据:
- //生成数据
- void CMy123Dlg::OnBnClickedButton1()
- {
- if(m_bModify)
- {
- int nRet = MessageBox("当前用户信息尚未保存,是否保存?","ALARM!",MB_YESNOCANCEL);
- switch(nRet)
- {
- case IDCANCEL:
- return;
- case IDYES:
- OnBnClickedButton2();
- break;
- case IDNO:
- default:
- break;
- }
- }
- //
- CTime t=CTime::GetCurrentTime();
- m_OccurDate = t.Format("%Y/%m/%d/%H:%M:%S");
- m_Data1.Format("%d",rand()%32767);
- m_Data2.Format("%d",rand()%32767);
- m_bModify = true;
- m_bNewUser = TRUE;
- UpdateData(FALSE);
- DestroyPhoto();
- Invalidate();
- }
复制代码 存储到数据库:
- //存储到数据库按钮
- void CMy123Dlg::OnBnClickedButton2()
- {
- if(!m_bModify)
- return;
- UpdateData();
- if(m_pBMPBuffer == NULL || m_hPhotoBitmap == NULL || m_OccurDate == "" || m_Data1 == ""|| m_Data2 == "")
- {
- AfxMessageBox("信息不完整。\r\n信息包括:故障图片,发生日期,故障数据1,2");
- return;
- }
- char *pBuf = m_pBMPBuffer;
- VARIANT varBLOB;
- SAFEARRAY *psa;
- SAFEARRAYBOUND rgsabound[1];
- try
- {
- if(m_bNewUser)
- m_pRecordset->AddNew();
- m_pRecordset->PutCollect("occurdate",_variant_t(m_OccurDate));
- m_pRecordset->PutCollect("data1",atol(m_Data1));
- m_pRecordset->PutCollect("data2",atol(m_Data2));
- if(pBuf)
- {
- rgsabound[0].lLbound = 0;
- rgsabound[0].cElements = m_nFileLen;
- psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
- for (long i = 0; i < (long)m_nFileLen; i++)
- SafeArrayPutElement (psa, &i, pBuf++);
- varBLOB.vt = VT_ARRAY | VT_UI1;
- varBLOB.parray = psa;
- m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB);
- }
- m_pRecordset->Update();
- }
- catch(_com_error *e)
- {
- }
- UpdateGrid();
- m_bNewUser = FALSE;
- m_bModify = FALSE;
- }
复制代码 删除数据:
- //删除数据
- void CMy123Dlg::OnBnClickedButton4()
- {
- if(m_pRecordset->adoEOF||m_pRecordset->BOF)
- {
- return;
- }
- DestroyPhoto(); ///清除原图像
- m_OccurDate.Empty();
- m_Data1.Empty();
- m_Data2.Empty();
- UpdateData(FALSE);
- //
- try
- {
- m_pRecordset->Delete(adAffectCurrent);
- m_pRecordset->Update();
- m_pRecordset->MoveFirst();
- }
- catch(_com_error &e)
- {
- }
- //
- ReadData();
- UpdateGrid();
- Invalidate();
- }
复制代码 左右浏览数据:
- //浏览前一数据
- void CMy123Dlg::OnBnClickedButton5()
- {
- if(m_bModify)///假如当前记录改动过,则保存
- OnBnClickedButton2();
- try
- {
- if(m_pRecordset->BOF)
- return;
- m_pRecordset->MovePrevious();
- }
- catch(_com_error *e)
- {
- }
- ReadData();
- Invalidate();
- }
- //浏览后一数据
- void CMy123Dlg::OnBnClickedButton6()
- {
- if(m_bModify)///假如当前记录改动过,则保存
- OnBnClickedButton2();
- try
- {
- if(m_pRecordset->adoEOF)
- return;
- m_pRecordset->MoveNext();
- }
- catch(_com_error *e)
- {
- }
- ReadData();
- Invalidate();
- }
复制代码 当然还有细节的部分可以下载例程查看学习。
电脑要安装有access。
|