⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olesvr2.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"

#ifdef AFX_OLE4_SEG
#pragma code_seg(AFX_OLE4_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW

//////////////////////////////////////////////////////////////////////////////
// COleServerItem implementation

COleServerItem::COleServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete)
{
	if (pServerDoc != NULL)
		ASSERT_VALID(pServerDoc);

	m_dwRef = 0;    // always start in disconnected state
	m_bAutoDelete = bAutoDelete;
	m_bNeedUnlock = FALSE;

	// initially, item does not have an extent
	m_sizeExtent.cx = 0;
	m_sizeExtent.cy = 0;

	// initialize advise holders
	m_lpOleAdviseHolder = NULL;
	m_lpDataAdviseHolder = NULL;

	// add presentation formats to the data source
	m_dataSource.m_nGrowBy = 1;
	FORMATETC formatEtc;
	formatEtc.ptd = NULL;
	formatEtc.dwAspect = DVASPECT_CONTENT;
	formatEtc.lindex = -1;

	// by default, a COleServerItem supports CF_METAFILEPICT
	formatEtc.cfFormat = CF_METAFILEPICT;
	formatEtc.tymed = TYMED_MFPICT;
	m_dataSource.DelayRenderData(0, &formatEtc);

	// add item to server document
	m_pDocument = NULL;
	if (pServerDoc != NULL)
		pServerDoc->AddItem(this);
	ASSERT(m_pDocument == pServerDoc);

	AfxOleLockApp();
}

COleServerItem::~COleServerItem()
{
	m_bAutoDelete = FALSE;  // no delete during destructor

	// release any advise holders
	RELEASE(m_lpOleAdviseHolder);
	RELEASE(m_lpDataAdviseHolder);

	ExternalDisconnect();

	// disconnect from the document
	COleServerDoc* pDoc = GetDocument();
	if (pDoc != NULL)
	{
		// remove external lock from it
		if (m_bNeedUnlock)
		{
			pDoc->LockExternal(FALSE, TRUE);
			m_bNeedUnlock = FALSE;
		}

		// reset m_pEmbeddedItem if destroying embedded item
		if (pDoc->m_pEmbeddedItem == this)
			pDoc->m_pEmbeddedItem = NULL;

		// remove from list
		pDoc->RemoveItem(this);
	}

	// cleanup any references
	AfxOleUnlockApp();
}

BOOL COleServerItem::IsBlank() const
{
	// server items are blank in order to keep them from serializing when
	//  COleDocument::Serialize is called.

	return TRUE;
}

BOOL COleServerItem::IsConnected() const
{
	// if item is connected in any way, return TRUE
	if (m_dwRef != 0)
		return TRUE;

	// otherwise check if embedded item and document is connected
	if (!IsLinkedItem() && GetDocument()->m_lpClientSite != NULL)
		return TRUE;

	return FALSE;   // not connected
}

void COleServerItem::NotifyClient(OLE_NOTIFICATION nCode, DWORD dwParam)
{
	switch (nCode)
	{
	// IDataObject notifications
	case OLE_CHANGED:
		if (m_lpDataAdviseHolder != NULL)
			m_lpDataAdviseHolder->SendOnDataChange(GetDataObject(), dwParam, 0);
		break;

	// IOleObject notifications
	case OLE_SAVED:
		if (m_lpOleAdviseHolder != NULL)
			m_lpOleAdviseHolder->SendOnSave();
		break;
	case OLE_CLOSED:
		if (m_lpOleAdviseHolder != NULL)
			m_lpOleAdviseHolder->SendOnClose();
		break;
	case OLE_RENAMED:
		if (m_lpOleAdviseHolder != NULL)
		{
			// Note: the moniker should already be updated for this to work
			LPMONIKER lpMoniker = (LPMONIKER)dwParam;
			m_lpOleAdviseHolder->SendOnRename(lpMoniker);
		}
		break;

	default:
		ASSERT(FALSE);
	}
}

/////////////////////////////////////////////////////////////////////////////
// Helpers for getting commonly used interfaces through interface map

LPDATAOBJECT COleServerItem::GetDataObject()
{
	LPDATAOBJECT lpDataObject =
		(LPDATAOBJECT)GetInterface(&IID_IDataObject);
	ASSERT(lpDataObject != NULL);
	return lpDataObject;
}

LPOLEOBJECT COleServerItem::GetOleObject()
{
	LPOLEOBJECT lpOleObject =
		(LPOLEOBJECT)GetInterface(&IID_IOleObject);
	ASSERT(lpOleObject != NULL);
	return lpOleObject;
}

/////////////////////////////////////////////////////////////////////////////
// COleServerItem overrides

BOOL COleServerItem::OnQueryUpdateItems()
{
	COleDocument* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// update all of the embedded objects
	POSITION pos = pDoc->GetStartPosition();
	COleClientItem* pItem;
	while ((pItem = pDoc->GetNextClientItem(pos)) != NULL)
	{
		// if any item is out-of-date, then this item is out-of-date
		if (pItem->m_lpObject->IsUpToDate() != NULL)
			return TRUE;    // update needed
	}
	return FALSE;   // update not needed
}

void COleServerItem::OnUpdateItems()
{
	COleDocument* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// update all of the embedded objects
	POSITION pos = pDoc->GetStartPosition();
	COleClientItem* pItem;
	while ((pItem = pDoc->GetNextClientItem(pos)) != NULL)
	{
		// update any out-of-date item
		if (pItem->m_lpObject->IsUpToDate() != NULL)
			pItem->m_lpObject->Update();
	}
}

BOOL COleServerItem::OnSetExtent(DVASPECT dwDrawAspect, const CSize& size)
{
	ASSERT_VALID(this);

	if (dwDrawAspect == DVASPECT_CONTENT)
	{
		m_sizeExtent = size;    // simply remember the extent
		return TRUE;
	}
	return FALSE;   // not implemented for that dwDrawAspect
}

BOOL COleServerItem::OnGetExtent(DVASPECT /*dwDrawAspect*/, CSize& rSize)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(&rSize, sizeof(CSize)));

	// the default implementation doesn't know what the extent is

	rSize.cx = 0;
	rSize.cy = 0;

	return FALSE;
}

void COleServerItem::OnDoVerb(LONG iVerb)
{
	switch (iVerb)
	{
	// open - maps to OnOpen
	case OLEIVERB_OPEN:
	case -OLEIVERB_OPEN-1:  // allows positive OLEIVERB_OPEN-1 in registry
		OnOpen();
		break;

	// primary, show, and unknown map to OnShow
	case OLEIVERB_PRIMARY:  // OLEIVERB_PRIMARY is 0 and "Edit" in registry
	case OLEIVERB_SHOW:
		OnShow();
		break;

	// hide maps to OnHide
	case OLEIVERB_HIDE:
	case -OLEIVERB_HIDE-1:  // allows positive OLEIVERB_HIDE-1 in registry
		OnHide();
		break;

	default:
		// negative verbs not understood should return E_NOTIMPL
		if (iVerb < 0)
			AfxThrowOleException(E_NOTIMPL);

		// positive verb not processed --
		//  according to OLE spec, primary verb should be executed
		//  instead.
		OnDoVerb(OLEIVERB_PRIMARY);

		// also, OLEOBJ_S_INVALIDVERB should be returned.
		AfxThrowOleException(OLEOBJ_S_INVALIDVERB);
	}
}

BOOL COleServerItem::OnDrawEx(CDC* pDC, DVASPECT nDrawAspect, CSize& rSize)
{
	ASSERT_VALID(pDC);
	ASSERT(AfxIsValidAddress(&rSize, sizeof(CSize)));

	if (nDrawAspect != DVASPECT_CONTENT)
		return FALSE;

	return OnDraw(pDC, rSize);
}

void COleServerItem::OnShow()
{
	ASSERT_VALID(this);

	// attempt in place activation (if not supported, fall back on "Open")
	COleServerDoc* pDoc = GetDocument();
	if (!pDoc->ActivateInPlace())
	{
		// by default OnShow() maps to OnOpen() if in-place activation
		//  not supported
		OnOpen();
	}
}

void COleServerItem::OnOpen()
{
	ASSERT_VALID(this);

	// default implementation shows the document
	COleServerDoc* pDoc = GetDocument();
	ASSERT(pDoc != NULL);
	pDoc->OnShowDocument(TRUE);
}

void COleServerItem::OnHide()
{
	ASSERT_VALID(this);

	// default implementation hides the document
	COleServerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->OnShowDocument(FALSE);
}

BOOL COleServerItem::GetMetafileData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
	ASSERT(lpStgMedium->tymed == TYMED_NULL);   // GetDataHere not valid
	ASSERT(lpStgMedium->pUnkForRelease == NULL);

	// medium must be TYMED_MFPICT -- cannot fill in existing HGLOBAL
	if (!(lpFormatEtc->tymed & TYMED_MFPICT) || lpStgMedium->hGlobal != NULL)
		return FALSE;

	// create appropriate memory metafile DC
	CMetaFileDC dc;
	if (!dc.Create())
		return FALSE;

	// create attribute DC according to lpFormatEtc->ptd
	HDC hAttribDC = _AfxOleCreateDC(lpFormatEtc->ptd);
	if (hAttribDC == NULL)
		return FALSE;
	dc.SetAttribDC(hAttribDC);

	// Paint directly into the metafile.
	CSize size(0, 0);
	BOOL bResult = OnDrawEx(&dc, (DVASPECT)lpFormatEtc->dwAspect, size);

	// attribute DC is no longer necessary
	dc.SetAttribDC(NULL);
	::DeleteDC(hAttribDC);

	if (!bResult)
	{
#ifdef _DEBUG
		if (afxTraceFlags & traceOle)
			TRACE0("calling COleServerItem::OnDrawEx()failed.\n");
#endif
		return FALSE;
	}

	HMETAFILE hMF = dc.Close();
	if (hMF == NULL)
		return FALSE;

	HGLOBAL hPict;
	if ((hPict =
		::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, sizeof(METAFILEPICT))) == NULL)
	{
		DeleteMetaFile(hMF);
		return FALSE;
	}
	LPMETAFILEPICT lpPict;
	if ((lpPict = (LPMETAFILEPICT)::GlobalLock(hPict)) == NULL)
	{
		DeleteMetaFile(hMF);
		::GlobalFree(hPict);
		return FALSE;
	}

	// set the metafile size
	lpPict->mm = MM_ANISOTROPIC;
	lpPict->hMF = hMF;
	if (size.cx == 0 && size.cy == 0 &&
		!OnGetExtent((DVASPECT)lpFormatEtc->dwAspect, size))
	{
		TRACE0("Warning: OnGetExtent failed during OnDrawEx --\n");
		TRACE0("\tpresentation metafile may be badly formed!\n");
	}
	lpPict->xExt = size.cx;
	lpPict->yExt = size.cy;  // HIMETRIC height
	if (lpPict->yExt < 0)
	{
		TRACE0("Warning: HIMETRIC natural size is negative.\n");
		lpPict->yExt = -lpPict->yExt;   // backward compatibility fix
	}

#ifdef _DEBUG
	if (lpPict->xExt == 0 || lpPict->yExt == 0)
	{
		// usually the natural extent is set to something interesting
		TRACE0("Warning: COleServerItem has no natural size --\n");
		TRACE0("\twill not work with some apps like MS Write.\n");
	}
#endif

	// return the medium with the hGlobal to the METAFILEPICT
	::GlobalUnlock(hPict);
	lpStgMedium->hGlobal = hPict;
	lpStgMedium->tymed = TYMED_MFPICT;
	return TRUE;
}

BOOL COleServerItem::OnSetColorScheme(const LOGPALETTE* /*lpLogPalette*/)
{
	ASSERT_VALID(this);

	return FALSE;   // default does nothing
}

BOOL COleServerItem::OnInitFromData(
	COleDataObject* /*pDataObject*/, BOOL /*bCreation*/)
{
	ASSERT_VALID(this);

	AfxThrowOleException(E_NOTIMPL);
	return FALSE;
}

void COleServerItem::CopyToClipboard(BOOL bIncludeLink)
{
	ASSERT_VALID(this);

	COleDataSource* pDataSource = OnGetClipboardData(bIncludeLink, NULL, NULL);

	// put it on the clipboard
	pDataSource->SetClipboard();
}

COleDataSource* COleServerItem::OnGetClipboardData(BOOL bIncludeLink,
	LPPOINT lpOffset, LPSIZE lpSize)
{
	ASSERT_VALID(this);

	COleDataSource* pDataSource = new COleDataSource;
	TRY
	{
		GetClipboardData(pDataSource, bIncludeLink, lpOffset, lpSize);
	}
	CATCH_ALL(e)
	{
		delete pDataSource;
		THROW_LAST();
	}
	END_CATCH_ALL

	ASSERT_VALID(pDataSource);
	return pDataSource;
}

DROPEFFECT COleServerItem::DoDragDrop(LPCRECT lpItemRect, CPoint ptOffset,
	BOOL bIncludeLink, DWORD dwEffects, LPCRECT lpRectStartDrag)
{
	ASSERT(AfxIsValidAddress(lpItemRect, sizeof(RECT)));
	ASSERT_VALID(this);

	ASSERT_VALID(this);

	DROPEFFECT dropEffect = DROPEFFECT_NONE;
	COleDataSource *pDataSource = NULL;
	TRY
	{
		// get clipboard data for this item
		CSize sizeItem(
			lpItemRect->right - lpItemRect->left,
			lpItemRect->bottom - lpItemRect->top);
		pDataSource = OnGetClipboardData(bIncludeLink, &ptOffset, &sizeItem);

		// add DROPEFFECT_LINK if link source is available
		LPDATAOBJECT lpDataObject = (LPDATAOBJECT)
			pDataSource->GetInterface(&IID_IDataObject);
		ASSERT(lpDataObject != NULL);
		FORMATETC formatEtc;
		formatEtc.cfFormat = (CLIPFORMAT)_oleData.cfLinkSource;
		formatEtc.ptd = NULL;
		formatEtc.dwAspect = DVASPECT_CONTENT;
		formatEtc.lindex = -1;
		formatEtc.tymed = (DWORD) -1;
		if (lpDataObject->QueryGetData(&formatEtc) == S_OK)
			dwEffects |= DROPEFFECT_LINK;

		// calculate default sensitivity rectangle
		CRect rectDrag;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -