FILE: OLE2BIN Sample - Storing COleClientItems in a DatabaseID: Q177911
|
The OLE2BIN sample demonstrates how to save and load an MFC COleClientItem
from a Access database (.mdb file). The storage and any COleClientItem data
are stored.
STEP2 of the Container tutorial sample was used as the starting point to
demonstrate this technique. A Database menu was added, with two submenus,
Save Object and Load Object. To save an object to the database, click a
COleClientItem to select it and then click Save Object on the Database
menu. You will be asked to provide a name for the object, which can then be
used later to load the object from the database.
To load an object, click Load Object on the Database menu. You will be
asked to select an object that was previously saved. When you first run the
sample, there is an object that has already been placed in the database.
The following file is available for download from the Microsoft Software Library:
OLE2BIN.EXEFor more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
Q119591 How to Obtain Microsoft Support Files from Online ServicesThe core functionality of the sample is located in two functions, CContainerView::OnDatabaseLoad() and CContainerView::OnDatabaseSave().
static const TCHAR szContents[] = _T("Contents");
#define INITIAL_ALLOC_SIZE 100000
void CContainerView::OnDatabaseSave()
{
LPLOCKBYTES pLockBytes = NULL;
LPSTORAGE pStorage = NULL;
ASSERT(m_pSelection != NULL);
CNameDlg dlg;
if (dlg.DoModal() == IDCANCEL || dlg.m_Name == "")
{
return;
}
CDatabase db;
if (!db.OpenEx("DRIVER=Microsoft Access Driver
(*.mdb);DBQ=BinDB.MDB;FIL=MS Access for Microsoft
Access;UID=Admin;PWD=;"))
{
AfxMessageBox("Access ODBC Driver not installed");
return;
}
CObjectSet rs(&db);
rs.Open();
rs.AddNew();
rs.m_Name = dlg.m_Name;
GlobalFree(rs.m_OleObject.m_hData);
rs.m_OleObject.m_hData = GlobalAlloc(GMEM_MOVEABLE,
INITIAL_ALLOC_SIZE);
if (FAILED(CreateILockBytesOnHGlobal(rs.m_OleObject.m_hData,FALSE,
&pLockBytes)))
{
AfxMessageBox("Unable to retrieve LockBytes");
return;
}
if (FAILED(StgCreateDocfileOnILockBytes(pLockBytes, STGM_DIRECT |
STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,
&pStorage)))
{
AfxMessageBox("Failure creating storage on LockBytes");
pLockBytes->Release();
return;
}
COleStreamFile file;
CFileException fe;
if (!file.CreateStream(pStorage, szContents,
CFile::modeReadWrite|CFile::shareExclusive|CFile::modeCreate,
&fe))
{
AfxThrowFileException(fe.m_cause, fe.m_lOsError);
}
// save to Contents stream
CArchive saveArchive(&file, CArchive::store |
CArchive::bNoFlushOnDelete);
saveArchive.m_pDocument = GetDocument();
saveArchive.m_bForceFlat = TRUE;
TRY
{
m_pSelection->Serialize(saveArchive);
saveArchive.Close();
file.Close();
// commit the storage
SCODE sc = pStorage->Commit(STGC_ONLYIFCURRENT);
if (sc != S_OK)
AfxThrowOleException(sc);
}
CATCH_ALL(e)
{
file.Abort(); // will not throw an exception
THROW_LAST();
}
END_CATCH_ALL
rs.SetFieldDirty(&rs.m_OleObject);
rs.SetFieldNull(&rs.m_OleObject, FALSE);
STATSTG statstg;
pLockBytes->Stat(&statstg, STATFLAG_NONAME);
rs.m_OleObject.m_dwDataLength = statstg.cbSize.LowPart;
rs.Update();
rs.Close();
pLockBytes->Release();
pStorage->Release();
}
void CContainerView::OnDatabaseLoad()
{
LPSTORAGE pStorage = NULL;
LPLOCKBYTES pLockBytes = NULL;
// Make certain there are objects in the database
// If there are, bring up dialog for user to select an object
CDatabase db;
if (!db.OpenEx("DRIVER=Microsoft Access Driver
(*.mdb);DBQ=BinDB.MDB;FIL=MS Access for Microsoft
Access;UID=Admin;PWD=;"))
{
AfxMessageBox("Access ODBC Driver not installed");
return;
}
CObjNameSet rsObjName(&db);
rsObjName.Open();
if (rsObjName.IsEOF())
{
rsObjName.Close();
AfxMessageBox("No objects exist in the database.");
return;
}
CObjDlg dlg(&rsObjName);
if (dlg.DoModal() == IDCANCEL)
{
return;
}
rsObjName.Close();
CObjectSet rs(&db);
CContainerItem * pItem = new CContainerItem;
rs.m_strFilter = "Name = '" + dlg.m_ObjectName + "'";
rs.Open();
if (FAILED(CreateILockBytesOnHGlobal(rs.m_OleObject.m_hData, FALSE,
&pLockBytes)))
{
AfxMessageBox("Unable to retrieve LockBytes");
return;
}
HRESULT hr = StgOpenStorageOnILockBytes(pLockBytes, NULL,
STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE , NULL,
0, &pStorage);
if (FAILED(hr))
{
AfxMessageBox("Failure opening storage");
pLockBytes->Release();
return;
}
COleStreamFile file;
CFileException fe;
if (!file.OpenStream(pStorage, szContents,
CFile::modeRead|CFile::shareExclusive, &fe))
{
if (fe.m_cause == CFileException::fileNotFound)
AfxThrowArchiveException(CArchiveException::badSchema);
else
AfxThrowFileException(fe.m_cause, fe.m_lOsError);
}
CArchive loadArchive(&file, CArchive::load |
CArchive::bNoFlushOnDelete);
loadArchive.m_pDocument = GetDocument();
loadArchive.m_bForceFlat = TRUE;
TRY
{
pItem->Serialize(loadArchive); // load main contents
loadArchive.Close();
file.Close();
}
CATCH_ALL(e)
{
file.Abort(); // will not throw an exception
// remove item because it didn't fully loaded
GetDocument()->RemoveItem(pItem);
THROW_LAST();
}
END_CATCH_ALL
rs.Close();
db.Close();
pLockBytes->Release();
GetDocument()->UpdateAllViews(NULL);
}
Additional query words: OLE Field BLOB Binary kbVC500 kbVC600
Keywords : kbsample kbDatabase kbMFC kbODBC kbVC
Version : WINNT:5.0
Platform : winnt
Issue type :
Last Reviewed: July 29, 1999