📄 olecli1.cpp
字号:
}
// create a memory based stream to write the moniker to
LPSTREAM lpStream;
if (::CreateStreamOnHGlobal(NULL, TRUE, &lpStream) != S_OK)
{
lpMoniker->Release();
AfxThrowMemoryException();
}
ASSERT(lpStream != NULL);
// write the moniker to the stream, and add it to the clipboard
SCODE sc = ::OleSaveToStream(lpMoniker, lpStream);
lpMoniker->Release();
if (sc != S_OK)
{
lpStream->Release();
AfxThrowOleException(sc);
}
// write the class ID of the document to the stream as well
CLSID clsid;
sc = m_lpObject->GetUserClassID(&clsid);
if (sc != S_OK)
{
lpStream->Release();
AfxThrowOleException(sc);
}
sc = WriteClassStm(lpStream, clsid);
if (sc != S_OK)
{
lpStream->Release();
AfxThrowOleException(sc);
}
// add it to the data source
lpStgMedium->tymed = TYMED_ISTREAM;
lpStgMedium->pstm = lpStream;
lpStgMedium->pUnkForRelease = NULL;
return TRUE;
}
void COleClientItem::GetObjectDescriptorData(
LPPOINT lpOffset, LPSIZE lpSize, LPSTGMEDIUM lpStgMedium)
{
USES_CONVERSION;
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
ASSERT(lpOffset == NULL ||
AfxIsValidAddress(lpOffset, sizeof(CPoint), FALSE));
POINTL pointT;
if (lpOffset != NULL)
{
pointT.x = lpOffset->x;
pointT.y = lpOffset->y;
((CDC*)NULL)->DPtoHIMETRIC((SIZE*)&pointT);
}
else
{
pointT.x = 0;
pointT.y = 0;
}
SIZE sizeT;
if (lpSize != NULL)
{
sizeT.cx = lpSize->cx;
sizeT.cy = lpSize->cy;
((CDC*)NULL)->DPtoHIMETRIC(&sizeT);
}
else
{
sizeT.cx = 0;
sizeT.cy = 0;
}
COleDocument* pDoc = GetDocument();
// get the object descriptor for the IOleObject
InterlockedIncrement(&m_dwRef);
HGLOBAL hGlobal = _AfxOleGetObjectDescriptorData(
m_lpObject, T2COLE(pDoc->GetPathName()), m_nDrawAspect, pointT, &sizeT);
InterlockedDecrement(&m_dwRef);
if (hGlobal == NULL)
AfxThrowMemoryException();
// setup the STGMEDIUM
lpStgMedium->tymed = TYMED_HGLOBAL;
lpStgMedium->hGlobal = hGlobal;
lpStgMedium->pUnkForRelease = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// Embedded COleClientItem operations
void COleClientItem::SetHostNames(LPCTSTR lpszHost, LPCTSTR lpszHostObj)
{
USES_CONVERSION;
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
ASSERT(AfxIsValidString(lpszHost));
ASSERT(AfxIsValidString(lpszHostObj));
CheckGeneral(m_lpObject->SetHostNames(T2COLE(lpszHost),
T2COLE(lpszHostObj)));
}
void COleClientItem::SetExtent(const CSize& size, DVASPECT nDrawAspect)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
CheckGeneral(m_lpObject->SetExtent(nDrawAspect, (SIZE*)&size));
}
/////////////////////////////////////////////////////////////////////////////
// COleClientItem OLE interface implementation
BEGIN_INTERFACE_MAP(COleClientItem, CDocItem)
INTERFACE_PART(COleClientItem, IID_IOleClientSite, OleClientSite)
INTERFACE_PART(COleClientItem, IID_IAdviseSink, AdviseSink)
INTERFACE_PART(COleClientItem, IID_IOleWindow, OleIPSite)
INTERFACE_PART(COleClientItem, IID_IOleInPlaceSite, OleIPSite)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Implementation of IOleClientSite
STDMETHODIMP_(ULONG) COleClientItem::XOleClientSite::AddRef()
{
METHOD_PROLOGUE_EX_(COleClientItem, OleClientSite)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleClientItem::XOleClientSite::Release()
{
METHOD_PROLOGUE_EX_(COleClientItem, OleClientSite)
return pThis->ExternalRelease();
}
STDMETHODIMP COleClientItem::XOleClientSite::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(COleClientItem, OleClientSite)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COleClientItem::XOleClientSite::SaveObject()
{
METHOD_PROLOGUE_EX(COleClientItem, OleClientSite)
ASSERT_VALID(pThis);
LPPERSISTSTORAGE lpPersistStorage =
QUERYINTERFACE(pThis->m_lpObject, IPersistStorage);
ASSERT(lpPersistStorage != NULL);
SCODE sc = S_OK;
if (lpPersistStorage->IsDirty() == S_OK)
{
// S_OK == S_TRUE != S_FALSE, therefore object is dirty!
sc = ::OleSave(lpPersistStorage, pThis->m_lpStorage, TRUE);
if (sc == S_OK)
sc = lpPersistStorage->SaveCompleted(NULL);
// mark the document as dirty, if save sucessful.
pThis->m_pDocument->SetModifiedFlag();
}
lpPersistStorage->Release();
return sc;
}
STDMETHODIMP COleClientItem::XOleClientSite::GetMoniker(
DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
{
METHOD_PROLOGUE_EX(COleClientItem, OleClientSite)
ASSERT_VALID(pThis);
USES_CONVERSION;
COleDocument* pDoc = pThis->GetDocument();
ASSERT_VALID(pDoc);
ASSERT(ppMoniker != NULL);
*ppMoniker = NULL;
switch (dwWhichMoniker)
{
case OLEWHICHMK_CONTAINER:
// return the current moniker for the document
*ppMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
break;
case OLEWHICHMK_OBJREL:
{
if (!pDoc->IsKindOf(RUNTIME_CLASS(COleLinkingDoc)))
break;
// don't return relative moniker if no document moniker
LPMONIKER lpMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
if (lpMoniker == NULL)
break;
lpMoniker->Release();
// relative monikers have to handle assignment correctly
switch (dwAssign)
{
case OLEGETMONIKER_ONLYIFTHERE:
if (!pThis->m_bMoniker)
break; // no moniker assigned, don't return one
// fall through...
case OLEGETMONIKER_TEMPFORUSER:
case OLEGETMONIKER_FORCEASSIGN:
{
// create item moniker from item name
TCHAR szItemName[OLE_MAXITEMNAME];
pThis->GetItemName(szItemName);
CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName),
ppMoniker);
// notify the object of the assignment
if (dwAssign != OLEGETMONIKER_TEMPFORUSER &&
*ppMoniker != NULL && !pThis->m_bMoniker)
{
pThis->m_bMoniker = TRUE;
VERIFY(pThis->m_lpObject->SetMoniker(
OLEWHICHMK_OBJREL, *ppMoniker) == S_OK);
ASSERT_VALID(pThis->m_pDocument);
pThis->m_pDocument->SetModifiedFlag();
}
}
break;
case OLEGETMONIKER_UNASSIGN:
pThis->m_bMoniker = FALSE;
break;
}
}
break;
case OLEWHICHMK_OBJFULL:
{
// get each sub-moniker: item & document
LPMONIKER lpMoniker1, lpMoniker2;
GetMoniker(dwAssign, OLEWHICHMK_CONTAINER, &lpMoniker1);
GetMoniker(dwAssign, OLEWHICHMK_OBJREL, &lpMoniker2);
// create composite moniker
if (lpMoniker1 != NULL && lpMoniker2 != NULL)
::CreateGenericComposite(lpMoniker1, lpMoniker2, ppMoniker);
// release sub-monikers
RELEASE(lpMoniker1);
RELEASE(lpMoniker2);
}
break;
}
return *ppMoniker != NULL ? S_OK : E_FAIL;
}
STDMETHODIMP COleClientItem::XOleClientSite::GetContainer(
LPOLECONTAINER* ppContainer)
{
#ifdef _DEBUG
METHOD_PROLOGUE_EX(COleClientItem, OleClientSite)
#else
METHOD_PROLOGUE_EX_(COleClientItem, OleClientSite)
#endif
// return the IOleItemContainer interface in the document
COleDocument* pDoc = pThis->GetDocument();
ASSERT_VALID(pDoc);
*ppContainer = pDoc->GetContainer();
return *ppContainer != NULL ? S_OK : E_NOINTERFACE;
}
STDMETHODIMP COleClientItem::XOleClientSite::ShowObject()
{
METHOD_PROLOGUE_EX(COleClientItem, OleClientSite)
ASSERT_VALID(pThis);
TRY
{
pThis->OnShowItem();
}
END_TRY
return S_OK;
}
STDMETHODIMP COleClientItem::XOleClientSite::OnShowWindow(BOOL fShow)
{
METHOD_PROLOGUE_EX(COleClientItem, OleClientSite)
ASSERT_VALID(pThis);
// ignore this if the item is already in-place
if (pThis->IsInPlaceActive())
return S_OK;
TRY
{
// store new state of object -- determines how object may be drawn
COleClientItem::ItemState uNewState;
uNewState = fShow ? COleClientItem::openState :
COleClientItem::loadedState;
if (uNewState != pThis->m_nItemState)
{
pThis->OnChange(OLE_CHANGED_STATE, (DWORD)uNewState);
pThis->m_nItemState = uNewState;
}
}
END_TRY
return S_OK;
}
STDMETHODIMP COleClientItem::XOleClientSite::RequestNewObjectLayout()
{
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////////////////////
// Implementation of IAdviseSink
STDMETHODIMP_(ULONG) COleClientItem::XAdviseSink::AddRef()
{
METHOD_PROLOGUE_EX_(COleClientItem, AdviseSink)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleClientItem::XAdviseSink::Release()
{
METHOD_PROLOGUE_EX_(COleClientItem, AdviseSink)
return pThis->ExternalRelease();
}
STDMETHODIMP COleClientItem::XAdviseSink::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(COleClientItem, AdviseSink)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP_(void) COleClientItem::XAdviseSink::OnDataChange(
LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
METHOD_PROLOGUE_EX(COleClientItem, AdviseSink)
ASSERT_VALID(pThis);
// Only interesting for advanced containers. Forward it such that
// containers do not have to implement the entire interface.
pThis->OnDataChange(lpFormatEtc, lpStgMedium);
}
STDMETHODIMP_(void) COleClientItem::XAdviseSink::OnViewChange(
DWORD aspects, LONG /*lindex*/)
{
METHOD_PROLOGUE_EX(COleClientItem, AdviseSink)
ASSERT_VALID(pThis);
pThis->OnChange(OLE_CHANGED, (DVASPECT)aspects);
}
STDMETHODIMP_(void) COleClientItem::XAdviseSink::OnRename(
LPMONIKER /*lpMoniker*/)
{
// only interesting to the OLE link object. Containers ignore this.
}
STDMETHODIMP_(void) COleClientItem::XAdviseSink::OnSave()
{
METHOD_PROLOGUE_EX(COleClientItem, AdviseSink)
ASSERT_VALID(pThis);
pThis->OnChange(OLE_SAVED, (DVASPECT)0);
}
STDMETHODIMP_(void) COleClientItem::XAdviseSink::OnClose()
{
METHOD_PROLOGUE_EX(COleClientItem, AdviseSink)
ASSERT_VALID(pThis);
pThis->OnChange(OLE_CLOSED, (DVASPECT)0);
}
/////////////////////////////////////////////////////////////////////////////
// COleClientItem diagnostics
#ifdef _DEBUG
void COleClientItem::AssertValid() const
{
CDocItem::AssertValid();
if (m_lpNewStorage != NULL)
ASSERT(m_bNeedCommit);
if (m_pView != NULL)
m_pView->AssertValid();
if (m_pInPlaceFrame != NULL)
m_pInPlaceFrame->AssertValid();
if (m_pInPlaceDoc != NULL)
m_pInPlaceDoc->AssertValid();
}
void COleClientItem::Dump(CDumpContext& dc) const
{
CDocItem::Dump(dc);
// shallow dump
dc << "m_lpObject = " << (void*)m_lpObject;
dc << "\nm_dwItemNumber = " << m_dwItemNumber;
dc << "\nm_nDrawAspect = " << (int)m_nDrawAspect;
dc << "\nm_scLast = " << m_scLast;
dc << "\nm_lpStorage = " << m_lpStorage;
dc << "\nm_lpLockBytes = " << m_lpLockBytes;
dc << "\nm_dwConnection = " << m_dwConnection;
dc << "\nm_bLinkUnavail = " << m_bLinkUnavail;
dc << "\nm_bMoniker = " << m_bMoniker;
dc << "\nm_lpNewStorage = " << m_lpNewStorage;
dc << "\nm_bNeedCommit = " << m_bNeedCommit;
dc << "\nm_nItemState = " << (int)m_nItemState;
dc << "\nm_pView = " << (void*)m_pView;
dc << "\nm_dwContainerStyle = " << m_dwContainerStyle;
dc << "\nm_pInPlaceFrame = " << (void*)m_pInPlaceFrame;
dc << "\nm_hWndServer = " << m_hWndServer;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// Inline function declarations expanded out-of-line
#ifndef _AFX_ENABLE_INLINES
// expand inlines for OLE client APIs
static char _szAfxOleInl[] = "afxole.inl";
#undef THIS_FILE
#define THIS_FILE _szAfxOleInl
#define _AFXOLECLI_INLINE
#define _AFXOLEDOBJ_INLINE
#include "afxole.inl"
#endif //!_AFX_ENABLE_INLINES
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
// IMPLEMENT_DYNAMIC for COleLinkingDoc here for better .OBJ granularity
IMPLEMENT_DYNAMIC(COleLinkingDoc, COleDocument)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -