CdbImages::CdbImages(CDatabase* pdb) : CRecordset(pdb) { //{{AFX_FIELD_INIT(CdbImages) m_nFields = 2;//数据库中有两个字段 //}}AFX_FIELD_INIT m_nDefaultType = snapshot;//数据库以快照形式打开 } CString CdbImages::GetDefaultConnect() { return _T("ODBC;DSN=MS Access Database");//以ODBC操作数据库 } CString CdbImages::GetDefaultSQL() { return _T("[Images]");//默认的操作是连接到数据库中的Images表 } void CdbImages::DoFieldExchange(CFieldExchange* pFX) { //{{AFX_FIELD_MAP(CdbImages) pFX->SetFieldType(CFieldExchange::outputColumn); RFX_LongBinary(pFX, _T("[Image]"), m_Image);//记录集中的成员对象和表中的OLE字段采用长二进制交换。 //}}AFX_FIELD_MAP } /////////////////////////////////////////////////////////// //从数据库中显示图像数据 CDatabase m_DB;//定义的数据库全局变量 CBitmap Bitmap;//定义的图像类全局变量,用以存储图像数据 void CImageView::OnOpenDateBase() { m_DB.Open(NULL, //以ODBC形式打开数据库 FALSE, FALSE, "ODBC;DRIVER={ Microsof Access Driver (*.mdb)};DBQ=Photo.mdb"); CdbImages dbImages(m_DB); CString strFileName ;// 用来存放临时文件名,以该临时文件存放读取的数据库的图像数据。 i=1;//I为临时文件号 StrFileName.Format("%s",i) dbImages.Open(); if (dbImages.IsEOF()) AfxMessageBox("Unable to get image from db"); else { char tmpPath[_MAX_PATH+1]; GetTempPath(_MAX_PATH,tmpPath);//得到临时文件的目录; strFileName.Insert(0,tmpPath);//生成临时文件名 CFile outFile(strFileName,CFile::modeCreate|CFile::modeWrite); //向临时文件写数据,数据库中数据读操作时关键是知道数据的长度,这可以从记录集的图像字段对应的长二进制成员变量m_Image的成员dwDataLength得到; LPSTR buffer = (LPSTR)GlobalLock(dbImages.m_Image.m_hData); outFile.WriteHuge(buffer,dbImages.m_Image.m_dwDataLength); GlobalUnlock(dbImages.m_Image.m_hData); outFile.Close(); //定义图像句柄; HBITMAP hbm = (HBITMAP)::LoadImage(NULL, strFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (Bitmap.Attach(hbm))//将图像句柄和Cbitmap对象联系起来 { BITMAP bm; Bitmap.GetBitmap(&bm);//获取图像尺寸 Bitmap.SetBitmapDimension(bm.bmWidth,bm.bmHeight); return; } Invalidate();//重画屏幕 } ///////////////////////////////////////////// void CImageView::OnDraw(CDC* pDC)//显示图像 { CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap* pImage = memDC.SelectObject(Bitmap); CSize imageSize = Bitmap.GetBitmapDimension(); pDC->BitBlt(0,0,imageSize.cx,imageSize.cy,&memDC,0,0,SRCCOPY); memDC.SelectObject(pImage); } ////////////////////////////////////////////////////// //以下是向数据中添加图像记录 void CImageView::OnSaveDateBase() {//打开图像文件 static char BASED_CODE szFilter[] = "Bitmap Files (*.bmp)|*.bmp||"; CdbImages dbImages(m_DB); CFileDialog fd(TRUE,NULL,NULL,0,szFilter,this); if (IDOK != fd.DoModal()) return; dbImages.Open();//打开数据库 dbImages.AddNew();//添加新的记录 CFile fileImage; CFileStatus fileStatus; fileImage.Open(fd.GetPathName(), CFile::modeRead); fileImage.GetStatus(fileStatus);//得到打开的图像文件的状态信息; dbImages.m_Image.m_dwDataLength = fileStatus.m_size; HGLOBAL hGlobal= GlobalAlloc(GPTR,fileStatus.m_size);//申请存放图像数据的空间。 dbImages.m_Image.m_hData = GlobalLock(hGlobal);//将该空间付给m_hData成员; //向缓冲区读图像数据 fileImage.ReadHuge(dbImages.m_Image.m_hData,fileStatus.m_size);//向m_Image读图像数据。 dbImages.SetFieldDirty(&dbImages.m_Image);//标志数据库已经修改; dbImages.SetFieldNull(&dbImages.m_Image,FALSE);//设置记录为NULL; dbImages.Update();//刷新数据库的记录 GlobalUnlock(hGlobal); dbImages.Close();
} |