📄 olecli1.cpp
字号:
void COleClientItem::WriteItemFlat(CArchive& ar)
{
ASSERT_VALID(this);
ASSERT(m_lpStorage != NULL);
ASSERT(m_lpLockBytes != NULL);
// save the OLE object to its storage first
LPPERSISTSTORAGE lpPersistStorage =
QUERYINTERFACE(m_lpObject, IPersistStorage);
ASSERT(lpPersistStorage != NULL);
SCODE sc;
if (GetDocument()->m_bCompoundFile || lpPersistStorage->IsDirty() == S_OK)
{
sc = ::OleSave(lpPersistStorage, m_lpStorage,
!GetDocument()->m_bCompoundFile);
lpPersistStorage->SaveCompleted(NULL);
}
lpPersistStorage->Release();
m_lpStorage->Commit(STGC_OVERWRITE);
ASSERT(::StgIsStorageILockBytes(m_lpLockBytes) == S_OK);
// attempt to get the handle to the global memory
HGLOBAL hStorage;
sc = ::GetHGlobalFromILockBytes(m_lpLockBytes, &hStorage);
if (sc != S_OK)
AfxThrowOleException(sc);
// first write a byte count
STATSTG statstg;
sc = m_lpLockBytes->Stat(&statstg, STATFLAG_NONAME);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(statstg.cbSize.HighPart == 0); // don't support >4GB objects
DWORD dwBytes = statstg.cbSize.LowPart;
ar << dwBytes;
// write the contents of the block
LPVOID lpBuf = GlobalLock(hStorage);
ASSERT(lpBuf != NULL);
ar.Write(lpBuf, (UINT)dwBytes);
::GlobalUnlock(hStorage);
}
void COleClientItem::GetItemStorageCompound()
{
USES_CONVERSION;
COleDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ASSERT(pDoc->m_bCompoundFile);
if (pDoc->m_lpRootStg == NULL)
{
ASSERT(pDoc->m_bEmbedded);
pDoc->m_bEmbedded = FALSE;
if (!pDoc->OnNewDocument())
{
TRACE0("Warning OnNewDocument failed during COleClientItem::CreateXXXX\n");
AfxThrowMemoryException();
}
}
ASSERT(pDoc->m_lpRootStg != NULL);
// get item name
TCHAR szItemName[OLE_MAXITEMNAME];
GetItemName(szItemName);
// create storage for this item
LPSTORAGE lpStorage;
SCODE sc = pDoc->m_lpRootStg->CreateStorage(T2COLE(szItemName),
STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE,
0, 0, &lpStorage);
if (sc != S_OK)
{
TRACE1("Warning: unable to create child storage %s.\n", szItemName);
// upon failure throw file exception (item will be cleaned up)
AfxThrowOleException(sc);
}
ASSERT(lpStorage != NULL);
// everything should have worked
m_lpStorage = lpStorage;
ASSERT(m_lpStorage != NULL);
}
void COleClientItem::ReadItemCompound(CArchive& ar)
{
USES_CONVERSION;
COleDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ASSERT(pDoc->m_lpRootStg != NULL);
ASSERT(pDoc->m_bCompoundFile);
ASSERT(m_lpStorage == NULL);
ASSERT(m_lpLockBytes == NULL);
if (ar.m_bForceFlat)
{
ReadItemFlat(ar);
RELEASE(m_lpStorage);
RELEASE(m_lpLockBytes);
// change the number to something definitely unique
m_dwItemNumber = GetNewItemNumber();
// create new storage
GetItemStorageCompound();
LPPERSISTSTORAGE lpPersistStorage =
QUERYINTERFACE(m_lpObject, IPersistStorage);
ASSERT(lpPersistStorage != NULL);
SCODE sc = ::OleSave(lpPersistStorage, m_lpStorage, FALSE);
if (FAILED(sc))
{
lpPersistStorage->Release();
CheckGeneral(sc);
}
VERIFY(lpPersistStorage->SaveCompleted(m_lpStorage) == S_OK);
lpPersistStorage->Release();
}
else
{
// get item name
TCHAR szItemName[OLE_MAXITEMNAME];
GetItemName(szItemName);
// open storage for this item
LPSTORAGE lpStorage;
SCODE sc = pDoc->m_lpRootStg->OpenStorage(T2COLE(szItemName), NULL,
STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE,
0, 0, &lpStorage);
if (sc != S_OK)
{
TRACE1("Warning: unable to open child storage %s.\n", szItemName);
// upon failure throw file exception (item will be cleaned up)
AfxThrowOleException(sc);
}
ASSERT(lpStorage != NULL);
// remember the storage
m_lpStorage = lpStorage;
ASSERT(m_lpStorage != NULL);
// attempt to load the object from the storage
LPUNKNOWN lpUnk = NULL;
sc = ::OleLoad(m_lpStorage, IID_IUnknown, GetClientSite(),
(LPLP)&lpUnk);
CheckGeneral(sc);
// get IOleObject interface for the newly loaded object
ASSERT(lpUnk != NULL);
m_lpObject = QUERYINTERFACE(lpUnk, IOleObject);
lpUnk->Release();
if (m_lpObject == NULL)
AfxThrowOleException(E_OUTOFMEMORY);
}
}
void COleClientItem::WriteItemCompound(CArchive& ar)
{
USES_CONVERSION;
COleDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ASSERT(pDoc->m_lpRootStg != NULL);
ASSERT(pDoc->m_bCompoundFile);
ASSERT(m_lpNewStorage == NULL);
if (ar.m_bForceFlat)
{
LPSTORAGE pTempStorage = m_lpStorage;
LPLOCKBYTES pTempLockBytes = m_lpLockBytes;
m_lpStorage = NULL;
m_lpLockBytes = NULL;
GetItemStorageFlat();
WriteItemFlat(ar);
RELEASE(m_lpStorage);
RELEASE(m_lpLockBytes);
m_lpStorage = pTempStorage;
m_lpLockBytes = pTempLockBytes;
return;
}
// get item name
TCHAR szItemName[OLE_MAXITEMNAME];
GetItemName(szItemName);
// determine destination storage
ASSERT(m_lpStorage != NULL);
LPSTORAGE lpStorage = m_lpStorage;
if (!pDoc->m_bSameAsLoad)
{
// need to create new storage for this item
SCODE sc = pDoc->m_lpRootStg->CreateStorage(T2COLE(szItemName),
STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE,
0, 0, &lpStorage);
if (sc != S_OK)
{
TRACE1("Warning: unable to create child storage %s.\n",
szItemName);
AfxThrowOleException(sc);
}
// remember the storage for CommitItem stage
m_lpNewStorage = lpStorage;
m_bNeedCommit = TRUE;
}
ASSERT(lpStorage != NULL);
// save dirty object
LPPERSISTSTORAGE lpPersistStorage =
QUERYINTERFACE(m_lpObject, IPersistStorage);
ASSERT(lpPersistStorage != NULL);
SCODE sc = S_OK;
if (!pDoc->m_bSameAsLoad || lpPersistStorage->IsDirty() == S_OK)
{
// call OleSave now and IPersistStorage::SaveCompleted later
sc = ::OleSave(lpPersistStorage, lpStorage, pDoc->m_bSameAsLoad);
}
lpPersistStorage->Release();
// if it fails, abort the save
if (FAILED(sc))
AfxThrowOleException(sc);
// now will need to call CommitItem for this item
m_bNeedCommit = TRUE;
lpStorage->Commit(STGC_ONLYIFCURRENT);
}
void COleClientItem::GetItemStorage()
{
if (GetDocument()->m_bCompoundFile)
GetItemStorageCompound();
else
GetItemStorageFlat();
}
void COleClientItem::ReadItem(CArchive& ar)
{
if (GetDocument()->m_bCompoundFile)
ReadItemCompound(ar);
else
ReadItemFlat(ar);
}
void COleClientItem::WriteItem(CArchive& ar)
{
if (GetDocument()->m_bCompoundFile)
WriteItemCompound(ar);
else
WriteItemFlat(ar);
}
void COleClientItem::CommitItem(BOOL bSuccess)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
if (!m_bNeedCommit)
return;
LPPERSISTSTORAGE lpPersistStorage =
QUERYINTERFACE(m_lpObject, IPersistStorage);
ASSERT(lpPersistStorage != NULL);
// forget about new storage if save failed along the way...
if (m_lpNewStorage != NULL && !bSuccess)
RELEASE(m_lpNewStorage);
// let the object remember the new storage
VERIFY(lpPersistStorage->SaveCompleted(m_lpNewStorage) == S_OK);
lpPersistStorage->Release();
// determine/remember new storage
if (m_lpNewStorage != NULL)
{
m_lpStorage->Release();
m_lpStorage = m_lpNewStorage;
m_lpNewStorage = NULL;
}
m_bNeedCommit = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// COleClientItem serialization
void COleClientItem::Serialize(CArchive& ar)
{
ASSERT_VALID(this);
CDocItem::Serialize(ar);
ASSERT(m_pDocument != NULL); // must 'SetDocument' first
if (ar.IsStoring())
{
ASSERT(m_lpObject != NULL);
// first, save the type flag (this is used for versioning)
ar << (DWORD)OT_OLE2;
ar << m_dwItemNumber; // save the item number
// write the view advise type to storage
ASSERT(m_lpViewObject != NULL);
DWORD dwAspect;
IAdviseSink* pAdviseSink;
pAdviseSink = NULL;
VERIFY(m_lpViewObject->GetAdvise(&dwAspect, NULL, &pAdviseSink) == S_OK);
if( pAdviseSink != NULL )
{
RELEASE(pAdviseSink);
}
ar << dwAspect; // save the display aspect
// write flag indicating whether to create moniker upon load
ar << (WORD)m_bMoniker;
// save current default display aspect
ar << (DWORD)m_nDrawAspect;
// save object to storage (calls OleSave)
WriteItem(ar);
}
else
{
ASSERT(m_lpObject == NULL);
// first, get the type flag (for OLE 1.0 compatible reading)
DWORD dwType;
ar >> dwType;
if (dwType != OT_OLE2)
AfxThrowArchiveException(CArchiveException::generic);
ar >> m_dwItemNumber; // get the item number
DWORD dwAspect; // read the display aspect (aspects that are cached)
ar >> dwAspect;
WORD bMoniker; // see if we should create & set the moniker
ar >> bMoniker;
DWORD nDrawAspect; // read the default display aspect
ar >> nDrawAspect;
m_nDrawAspect = (DVASPECT)nDrawAspect;
// read the OLE object from storage (calls OleLoad)
ReadItem(ar);
// finish OLE object creation process, setup advises, etc.
if (!FinishCreate(S_OK))
AfxThrowArchiveException(CArchiveException::generic);
if (bMoniker)
{
// force moniker creation by calling GetMoniker
LPMONIKER lpMoniker;
if (GetClientSite()->GetMoniker(OLEGETMONIKER_FORCEASSIGN,
OLEWHICHMK_OBJREL, &lpMoniker) == S_OK)
{
ASSERT(lpMoniker != NULL);
lpMoniker->Release();
ASSERT(m_bMoniker); // moniker should have been assigned
}
}
// fix up the document's m_dwNextItemNumber
if (m_dwItemNumber >= GetDocument()->m_dwNextItemNumber)
GetDocument()->m_dwNextItemNumber = m_dwItemNumber + 1;
}
}
/////////////////////////////////////////////////////////////////////////////
// default callback implementation
void COleClientItem::OnChange(OLE_NOTIFICATION nCode, DWORD /*dwParam*/)
{
ASSERT_VALID(this);
switch (nCode)
{
case OLE_CLOSED:
break; // no default implementation
case OLE_CHANGED:
case OLE_SAVED:
ASSERT(m_pDocument != NULL);
m_pDocument->SetModifiedFlag();
break;
case OLE_CHANGED_STATE:
case OLE_CHANGED_ASPECT:
break; // no default implementation
default:
ASSERT(FALSE);
}
ASSERT_VALID(this);
}
void COleClientItem::OnDataChange(
LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/)
{
ASSERT(FALSE); // derivative must override -- must not call base class
}
void COleClientItem::OnGetItemPosition(CRect& /*rPosition*/)
{
// default does nothing
}
void COleClientItem::OnGetClipRect(CRect& rClipRect)
{
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(&rClipRect, sizeof(RECT)));
// default clips rectClip to client area of the active view
ASSERT_VALID(m_pView);
m_pView->GetClientRect(&rClipRect);
}
void COleClientItem::OnShowItem()
{
ASSERT_VALID(this);
CDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// attempt to use m_pView set during activation
CView* pView = m_pView;
if (pView == NULL)
{
// otherwise, find the first view of this document
POSITION pos = pDoc->GetFirstViewPosition();
if (pos == NULL || (pView = pDoc->GetNextView(pos)) == NULL)
return;
}
CFrameWnd* pFrameWnd = pView->GetParentFrame();
if (pFrameWnd != NULL)
{
// activate frame holding view
pFrameWnd->ActivateFrame();
pFrameWnd->OnUpdateFrameTitle(TRUE);
// activate app frame if necessary
pFrameWnd = pFrameWnd->GetParentFrame();
if (pFrameWnd != NULL)
{
ASSERT_KINDOF(CFrameWnd, pFrameWnd);
pFrameWnd->ActivateFrame();
pFrameWnd->OnUpdateFrameTitle(TRUE);
}
}
if (!pDoc->GetPathName().IsEmpty())
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -