Download demo project - 29 Kb
At times, storing images and other types of documents like
word document, or excel spread sheet or even a compressed zip
file in the database is inevitable. MFC provides a supporting
class to handle these BLOBs called CLongBinary. It is just a
wrapper around the HGLOBAL of WIN32. But how do you use it? The
wizard creates a member variable of type CLongBinary in your
record set object and also creates the corresponding RFX routine
(RFX_LongBinary).
Okay, does it mean that you can use this member just like any
other variable? No, That's where this document comes in handy.
For regular data types, all you have to is create an instance of
the recordset object, assign the values and call Update. But for
BLOBs, you have to do something special. For inserting BLOBs, you
have to remember 3 points.
- Allocate and lock the storage buffer using GlobalAlloc()
and GlobalLock() calls
- Prepare the recordset for blob operation using
SetFieldDirty() and SetFieldNull() calls
- Unlock the storage buffer
By default, the destructor of the CLongBinary will delete the
buffer using GlobalFree() call. So you don't have to bother about
freeing the memory. Reading from the database is pretty simple.
All you have to do is lock the buffer.
Following code snippet shows how to do this in the actual
code:
try
{
dbImages.Open();
dbImages.AddNew();
CFile fileImage;
CFileStatus fileStatus;
fileImage.Open("c:\\winnt\\winnt256.bmp", CFile::modeRead);
fileImage.GetStatus(fileStatus);
dbImages.m_BLOBName = fileImage.GetFileTitle();
dbImages.m_BLOBImage.m_dwDataLength = fileStatus.m_size;
HGLOBAL hGlobal = GlobalAlloc(GPTR,fileStatus.m_size);
dbImages.m_BLOBImage.m_hData = GlobalLock(hGlobal);
fileImage.ReadHuge(dbImages.m_BLOBImage.m_hData,fileStatus.m_size);
dbImages.SetFieldDirty(&dbImages.m_BLOBImage);
dbImages.SetFieldNull(&dbImages.m_BLOBImage,FALSE);
dbImages.Update();
GlobalUnlock(hGlobal);
dbImages.Close();
pList->InsertItem(0,fileImage.GetFileTitle());
}
catch(CException* pE)
{
pE->ReportError();
pE->Delete();
return;
}
CdbImages dbImages(&theApp.m_DB);
CString strFileName = pList->GetItemText(nIndex,0);
dbImages.m_strFilter.Format("BLOBName = '%s'",strFileName);
try
{
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);
LPSTR buffer = (LPSTR)GlobalLock(dbImages.m_BLOBImage.m_hData);
outFile.WriteHuge(buffer,dbImages.m_BLOBImage.m_dwDataLength);
GlobalUnlock(dbImages.m_BLOBImage.m_hData);
outFile.Close();
theApp.OpenDocumentFile(strFileName);
}
dbImages.Close();
}
catch(CException* pE)
{
pE->ReportError();
pE->Delete();
return;
}
The demo project uses an Access database to store the images.
This project also demonstrates the following:
- DSN - less Connection to MS Access database
- Dialog Bars
- Image Display in CScrollView
The images are displayed using the simplest technique of using
BitBlt() call. It does not use any Palettes because it is beyond
the scope of this article.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.