📄 olelink.cpp
字号:
--m_bDeferErrors;
if (m_pLastException != NULL)
{
ASSERT_VALID(m_pLastException);
if (sc == S_OK)
sc = COleException::Process(m_pLastException);
// Note: See note above in ReportSaveLoadException for
// a comment regarding the special treatment of m_bAutoDelete.
++m_pLastException->m_bAutoDelete;
// now get rid of the exception that we saved
m_pLastException->Delete();
m_pLastException = NULL;
}
return sc;
}
/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc OLE interface implementation
BEGIN_INTERFACE_MAP(COleLinkingDoc, COleDocument)
INTERFACE_PART(COleLinkingDoc, IID_IPersist, PersistFile)
INTERFACE_PART(COleLinkingDoc, IID_IPersistFile, PersistFile)
INTERFACE_PART(COleLinkingDoc, IID_IParseDisplayName, OleItemContainer)
INTERFACE_PART(COleLinkingDoc, IID_IOleContainer, OleItemContainer)
INTERFACE_PART(COleLinkingDoc, IID_IOleItemContainer, OleItemContainer)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc::XPersistFile implementation
STDMETHODIMP_(ULONG) COleLinkingDoc::XPersistFile::AddRef()
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleLinkingDoc::XPersistFile::Release()
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
return pThis->ExternalRelease();
}
STDMETHODIMP COleLinkingDoc::XPersistFile::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COleLinkingDoc::XPersistFile::GetClassID(LPCLSID lpClassID)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
// this is sometimes called for documents not attached to servers!
if (pThis->m_pFactory == NULL)
{
*lpClassID = CLSID_NULL;
return E_FAIL;
}
// get the class ID from the connected server object
ASSERT_VALID(pThis->m_pFactory);
*lpClassID = pThis->m_pFactory->GetClassID();
return S_OK;
}
STDMETHODIMP COleLinkingDoc::XPersistFile::IsDirty()
{
METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
return pThis->IsModified() ? S_OK : S_FALSE;
}
STDMETHODIMP COleLinkingDoc::XPersistFile::Load(
LPCOLESTR lpszFileName, DWORD /*dwMode*/)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
ASSERT_VALID(pThis);
USES_CONVERSION;
CString strFileName;
SCODE sc = E_FAIL;
pThis->BeginDeferErrors();
LPCTSTR lpszFileNameT = OLE2CT(lpszFileName);
TRY
{
BOOL bUserCtrl = AfxOleGetUserCtrl();
// delegate to file-based Open implementation
if (!pThis->OnOpenDocument(lpszFileNameT))
{
AfxOleSetUserCtrl(bUserCtrl);
return sc;
}
pThis->SendInitialUpdate();
// set the path name, but don't add to MRU list
pThis->SetPathName(lpszFileNameT, FALSE);
AfxOleSetUserCtrl(bUserCtrl);
sc = S_OK;
}
END_TRY
sc = pThis->EndDeferErrors(sc);
ASSERT_VALID(pThis);
return sc;
}
STDMETHODIMP COleLinkingDoc::XPersistFile::Save(
LPCOLESTR lpszFileName, BOOL fRemember)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
ASSERT_VALID(pThis);
USES_CONVERSION;
CString strFileName;
SCODE sc = E_FAIL;
pThis->BeginDeferErrors();
TRY
{
// delegate to file-based Save/Save As implementation
ASSERT(pThis->m_bRemember);
pThis->m_bRemember = fRemember;
pThis->OnSaveDocument(OLE2CT(lpszFileName));
sc = S_OK;
}
END_TRY
sc = pThis->EndDeferErrors(sc);
ASSERT_VALID(pThis);
return sc;
}
STDMETHODIMP COleLinkingDoc::XPersistFile::SaveCompleted(LPCOLESTR lpszFileName)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
ASSERT_VALID(pThis);
USES_CONVERSION;
TRY
{
// set the path name, but don't add to MRU list
pThis->SetPathName(OLE2CT(lpszFileName), FALSE);
}
END_TRY
ASSERT_VALID(pThis);
return S_OK;
}
STDMETHODIMP COleLinkingDoc::XPersistFile::GetCurFile(LPOLESTR* lplpszFileName)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
*lplpszFileName = NULL;
// use title if no document
LPCTSTR lpszResult;
if (pThis->m_strPathName.IsEmpty())
lpszResult = pThis->m_strTitle;
else
lpszResult = pThis->m_strPathName;
ASSERT(lpszResult != NULL);
// allocate memory for the file name
*lplpszFileName = AfxAllocTaskOleString(lpszResult);
if (*lplpszFileName == NULL)
return E_OUTOFMEMORY;
ASSERT_VALID(pThis);
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// Implementation of IOleItemContainer
// (supports linking to embeddings and linking to pseudo-objects)
STDMETHODIMP_(ULONG) COleLinkingDoc::XOleItemContainer::AddRef()
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleLinkingDoc::XOleItemContainer::Release()
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
return pThis->ExternalRelease();
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::EnumObjects(
DWORD /*grfFlags*/, LPENUMUNKNOWN* ppEnumUnknown)
{
*ppEnumUnknown = NULL;
return E_NOTIMPL;
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::ParseDisplayName(LPBC lpbc,
LPOLESTR lpszDisplayName, ULONG* cchEaten, LPMONIKER* ppMoniker)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
USES_CONVERSION;
// reset all OUT parameters
*ppMoniker = NULL;
TCHAR szItemName[OLE_MAXNAMESIZE];
LPTSTR lpszDest = szItemName;
LPCTSTR lpszSrc = OLE2CT(lpszDisplayName);
// skip leading delimiters
int cEaten = 0;
while (*lpszSrc != '\0' && (*lpszSrc == '\\' || *lpszSrc == '/' ||
*lpszSrc == ':' || *lpszSrc == '!' || *lpszSrc == '['))
{
if (_istlead(*lpszSrc))
++lpszSrc, ++cEaten;
++lpszSrc;
++cEaten;
}
// parse next token in szItemName
while (*lpszSrc != '\0' && *lpszSrc != '\\' && *lpszSrc != '/' &&
*lpszSrc != ':' && *lpszSrc != '!' && *lpszSrc != '[' &&
cEaten < OLE_MAXNAMESIZE-1)
{
if (_istlead(*lpszSrc))
*lpszDest++ = *lpszSrc++, ++cEaten;
*lpszDest++ = *lpszSrc++;
++cEaten;
}
*cchEaten = cEaten;
*lpszDest = 0;
// attempt to get the object
LPUNKNOWN lpUnknown;
SCODE sc = GetObject(T2OLE(szItemName), BINDSPEED_INDEFINITE, lpbc,
IID_IUnknown, (LPLP)&lpUnknown);
if (sc != S_OK)
return sc;
// item name found -- create item moniker for it
lpUnknown->Release();
return CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName), ppMoniker);
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::LockContainer(BOOL fLock)
{
METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
pThis->LockExternal(fLock, TRUE);
return S_OK;
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::GetObject(
LPOLESTR lpszItem, DWORD dwSpeedNeeded, LPBINDCTX /*pbc*/, REFIID riid,
LPVOID* ppvObject)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
ASSERT_VALID(pThis);
USES_CONVERSION;
*ppvObject = NULL;
SCODE sc = MK_E_NOOBJECT;
TRY
{
LPCTSTR lpszItemT = OLE2CT(lpszItem);
// check for link to embedding
COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(lpszItemT);
if (pClientItem != NULL)
{
ASSERT_VALID(pClientItem);
sc = S_OK;
// item found -- make sure it is running
if (!::OleIsRunning(pClientItem->m_lpObject))
{
// should not run the object if bind-speed is immediate
if (dwSpeedNeeded != BINDSPEED_INDEFINITE)
sc = MK_E_EXCEEDEDDEADLINE;
else
{
// bind speed is not immediate -- so run the object
sc = OleRun(pClientItem->m_lpObject);
}
}
if (sc == S_OK)
{
// return the object with appropriate interface
sc = pClientItem->m_lpObject->QueryInterface(riid, ppvObject);
}
}
else
{
// check for link to pseudo object
COleServerItem* pServerItem = pThis->OnGetLinkedItem(lpszItemT);
if (pServerItem != NULL)
{
if (!pServerItem->m_bNeedUnlock)
{
// when a link is bound, the document must be kept alive
pThis->LockExternal(TRUE, FALSE);
pServerItem->m_bNeedUnlock = TRUE;
}
// matching item found -- query for the requested interface
sc = pServerItem->ExternalQueryInterface(&riid, ppvObject);
}
}
}
END_TRY
return sc;
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::GetObjectStorage(
LPOLESTR lpszItem, LPBINDCTX /*pbc*/, REFIID riid, LPVOID* ppvStorage)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
ASSERT_VALID(pThis);
USES_CONVERSION;
*ppvStorage = NULL;
// only IStorage is supported
if (riid != IID_IStorage)
return E_UNEXPECTED;
// check for link to embedding
COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(OLE2CT(lpszItem));
if (pClientItem != NULL)
{
ASSERT_VALID(pClientItem);
// if object has no storage, can't return it!
if (pClientItem->m_lpStorage != NULL)
{
// found matching item -- return the storage
*ppvStorage = pClientItem->m_lpStorage;
pClientItem->m_lpStorage->AddRef();
return S_OK;
}
}
return MK_E_NOSTORAGE;
}
STDMETHODIMP COleLinkingDoc::XOleItemContainer::IsRunning(LPOLESTR lpszItem)
{
METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
ASSERT_VALID(pThis);
USES_CONVERSION;
// check for link to embedding
LPCTSTR lpszItemT = OLE2CT(lpszItem);
COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(lpszItemT);
if (pClientItem != NULL)
{
ASSERT_VALID(pClientItem);
if (!::OleIsRunning(pClientItem->m_lpObject))
return S_FALSE;
return S_OK; // item is in document and is running
}
// check for link to pseudo object
SCODE sc = MK_E_NOOBJECT;
TRY
{
COleServerItem* pServerItem = pThis->OnGetLinkedItem(lpszItemT);
if (pServerItem != NULL)
sc = S_OK;
}
END_TRY
return sc;
}
/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc diagnostics
#ifdef _DEBUG
void COleLinkingDoc::AssertValid() const
{
COleDocument::AssertValid();
if (m_pFactory != NULL)
m_pFactory->AssertValid();
}
void COleLinkingDoc::Dump(CDumpContext& dc) const
{
COleDocument::Dump(dc);
dc << "\nm_dwRegister = " << m_dwRegister;
dc << "\nm_bVisibleLock = " << m_bVisibleLock;
if (m_pFactory != NULL)
dc << "\nwith factory: " << m_pFactory;
else
dc << "\nwith no factory";
dc << "\n";
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -