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

📄 mainview.cpp

📁 学习COM组件编程的入门示例源代码。与《COM原理与应用》一书配套。
💻 CPP
📖 第 1 页 / 共 3 页
字号:

BOOL CMainView::OnDrop(COleDataObject* pDataObject,
	DROPEFFECT dropEffect, CPoint point)
{
	ASSERT_VALID(this);

	// clean up focus rect
	OnDragLeave();

	// offset point as appropriate for dragging
	GetObjectInfo(pDataObject, &m_dragSize, &m_dragOffset);
	CClientDC dc(NULL);
	dc.HIMETRICtoDP(&m_dragSize);
	dc.HIMETRICtoDP(&m_dragOffset);
	point -= m_dragOffset;

	// if move within the view
	ClientToDoc(point);
	if ((dropEffect & DROPEFFECT_MOVE) && m_bInDrag)
	{
		ASSERT(m_pSelection != NULL);
		m_bInDrag = FALSE; // signal drag code that a move happened
		// set top-left based on point of drop
		CRect rect = m_pSelection->GetRect();
		if (rect.TopLeft() != point) // if moved
		{
			m_pSelection->Move(CRect(point,rect.Size()));
			GetDocument()->SetModifiedFlag();
		}
	}
	// check and paste link
	else if ((dropEffect & DROPEFFECT_LINK) && DoPasteItem(TRUE, pDataObject, &point))
		return TRUE;

	// paste embedding/static
	else if (DoPasteItem(FALSE, pDataObject, &point))
		return TRUE;

	return FALSE;
}

BOOL CMainView::GetObjectInfo(COleDataObject* pDataObject,
	CSize* pSize, CSize* pOffset)
{
	ASSERT(pSize != NULL);

	// get object descriptor data
	HGLOBAL hObjDesc = pDataObject->GetGlobalData(m_cfObjectDescriptor);
	if (hObjDesc == NULL)
	{
		if (pOffset != NULL)
			*pOffset = CSize(0, 0); // fill in defaults instead
		*pSize = CSize(0, 0);
		return FALSE;
	}
	ASSERT(hObjDesc != NULL);

	// otherwise, got CF_OBJECTDESCRIPTOR ok.  Lock it down and extract size.
	LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR)GlobalLock(hObjDesc);
	ASSERT(pObjDesc != NULL);
	pSize->cx = (int)pObjDesc->sizel.cx;
	pSize->cy = (int)pObjDesc->sizel.cy;
	if (pOffset != NULL)
	{
		pOffset->cx = (int)pObjDesc->pointl.x;
		pOffset->cy = (int)pObjDesc->pointl.y;
	}
	GlobalUnlock(hObjDesc);
	GlobalFree(hObjDesc);

	// successfully retrieved pSize & pOffset info
	return TRUE;
}

DROPEFFECT CMainView::OnDragEnter(COleDataObject* pDataObject,
	DWORD grfKeyState, CPoint point)
{
	ASSERT(m_prevDropEffect == DROPEFFECT_NONE);

	GetObjectInfo(pDataObject, &m_dragSize, &m_dragOffset);
	CClientDC dc(NULL);
	dc.HIMETRICtoDP(&m_dragSize);
	dc.HIMETRICtoDP(&m_dragOffset);

	return OnDragOver(pDataObject, grfKeyState, point);
}

DROPEFFECT CMainView::OnDragOver(COleDataObject*,
	DWORD grfKeyState, CPoint point)
{
	point -= m_dragOffset;  // adjust target rect by original cursor offset

	// check for point outside logical area -- i.e. in hatched region
	// GetTotalSize() returns the size passed to SetScrollSizes
	CRect rectScroll(CPoint(0, 0), GetTotalSize());

	CRect rectItem(point,m_dragSize);
	if (rectItem.IsRectEmpty())
	{
		// some apps might have a null size in the object descriptor...
		rectItem.InflateRect(1,1);
	}
	rectItem.OffsetRect(GetDeviceScrollPosition());

	DROPEFFECT de = DROPEFFECT_NONE;
	CRect rectTemp;
	if (rectTemp.IntersectRect(rectScroll, rectItem))
	{
		// check for force link
		if ((grfKeyState & (MK_CONTROL|MK_SHIFT)) == (MK_CONTROL|MK_SHIFT))
			de = DROPEFFECT_LINK;
		// check for force copy
		else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
			de = DROPEFFECT_COPY;
		// check for force move
		else if ((grfKeyState & MK_ALT) == MK_ALT)
			de = DROPEFFECT_MOVE;
		// default -- recommended action is move
		else
			de = DROPEFFECT_MOVE;
	}

	if (point == m_dragPoint)
		return de;

	// otherwise, cursor has moved -- need to update the drag feedback
	CClientDC dc(this);
	if (m_prevDropEffect != DROPEFFECT_NONE)
	{
		// erase previous focus rect
		dc.DrawFocusRect(CRect(m_dragPoint, m_dragSize));
	}
	m_prevDropEffect = de;
	if (m_prevDropEffect != DROPEFFECT_NONE)
	{
		m_dragPoint = point;
		dc.DrawFocusRect(CRect(point, m_dragSize));
	}
	return de;
}

void CMainView::OnDragLeave()
{
	CClientDC dc(this);
	if (m_prevDropEffect != DROPEFFECT_NONE)
	{
		dc.DrawFocusRect(CRect(m_dragPoint,m_dragSize)); // erase previous focus rect
		m_prevDropEffect = DROPEFFECT_NONE;
	}
}

/////////////////////////////////////////////////////////////////////////////
// Commands for switching display aspects

void CMainView::OnObjectDisplayContent()
{
	if (m_pSelection == NULL)
		return;
	ASSERT_VALID(m_pSelection);
	m_pSelection->Invalidate();
	m_pSelection->SetDrawAspect(DVASPECT_CONTENT);
	m_pSelection->UpdateExtent();
	m_pSelection->Invalidate();
}

void CMainView::OnUpdateObjectDisplayContent(CCmdUI* pCmdUI)
{
	if (m_pSelection == NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	ASSERT_VALID(m_pSelection);
	pCmdUI->SetCheck(m_pSelection->GetDrawAspect() == DVASPECT_CONTENT);
	pCmdUI->Enable(TRUE);
}

void CMainView::OnObjectDisplayAsIcon()
{
	if (m_pSelection == NULL)
		return;
	ASSERT_VALID(m_pSelection);
	m_pSelection->Invalidate();
	m_pSelection->SetDrawAspect(DVASPECT_ICON);
	m_pSelection->UpdateExtent();
	m_pSelection->Invalidate();
}

void CMainView::OnUpdateObjectDisplayAsIcon(CCmdUI* pCmdUI)
{
	if (m_pSelection == NULL)
	{
		pCmdUI->Enable(FALSE);
		return;
	}
	ASSERT_VALID(m_pSelection);
	pCmdUI->SetCheck(m_pSelection->GetDrawAspect() == DVASPECT_ICON);
	pCmdUI->Enable(TRUE);
}

void CMainView::UpdateActiveItem()
{
	// when there is an active item visible, sizing the window may cause
	//  more/less of the in-place object to become visible.
	//  (ie. the clipping rectangle changes with the size of the window)
	// a container supporting scrolling would also have to do this
	//  when scrolling the contents of the window.

	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL &&
		pActiveItem->GetItemState() == COleClientItem::activeUIState &&
		pActiveItem->GetActiveView() == this)
	{
		// this will update the item rectangles by calling
		//  OnGetPosRect & OnGetClipRect.
		pActiveItem->SetItemRects();
	}
}

void CMainView::OnUpdateEditClone(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_pSelection != NULL);
}

void CMainView::OnEditClone()
{
	if (m_pSelection == NULL)
		return;

	BeginWaitCursor();

	CRectItem* pItem = NULL;
	TRY
	{
		// create item from dialog results
		pItem = GetDocument()->CreateItem();
		if (!pItem->CreateCloneFrom(m_pSelection))
			AfxThrowMemoryException();  // any exception will do

		// offset it so we can see the clone easier
		CRect rect(20, 20, 0, 0);
		ClientToDoc(rect);
		pItem->m_ptPos.x += rect.left;
		pItem->m_ptPos.y += rect.top;
		ASSERT_VALID(pItem);
	}
	CATCH_ALL(e)
	{
		// cleanup item, if allocated
		if (pItem != NULL)
			GetDocument()->DeleteItem(pItem);

		AfxMessageBox(IDP_FAILED_TO_CREATE);
	}
	END_CATCH_ALL

	EndWaitCursor();
}

void CMainView::OnPasteSpecial()
{
	COlePasteSpecialDialog dlg;
	dlg.AddFormat(CMainDoc::m_cfPrivate, TYMED_HGLOBAL,
		IDS_PRIVATE_CF_DESCR, FALSE, FALSE);
	dlg.AddStandardFormats();
	if (dlg.DoModal() != IDOK)
		return;

	CRectItem* pItem = NULL;
	TRY
	{
		// Get the clipboard format of the selected
		CLIPFORMAT cf = dlg.m_ps.arrPasteEntries[dlg.m_ps.nSelectedIndex].fmtetc.cfFormat;
		if (cf == CMainDoc::m_cfPrivate)
		{
			BOOL bLink = dlg.GetSelectionType() ==
				COlePasteSpecialDialog::pasteLink;
			COleDataObject dataObject;
			dataObject.Attach(dlg.m_ps.lpSrcDataObj, FALSE);
			pItem = DoPasteItem(bLink, &dataObject, NULL, cf);

			// try to get initial presentation data
			pItem->UpdateLink();
		}
		else
		{
			pItem = GetDocument()->CreateItem();
			if (!dlg.CreateItem(pItem))
			{
				TRACE0("Warning: paste special failed to create item.\n");
				AfxThrowMemoryException();
			}

			// try to get initial presentation data
			pItem->UpdateLink();

			// try to get initial extent
			pItem->UpdateExtent();

			// allow document to offset item to avoid direct superimposition
			GetDocument()->AdjustItemPosition(pItem);

			// set the selection with bSafeSelect = TRUE
			SetSelection(pItem, TRUE);
			GetDocument()->SetModifiedFlag();
			GetDocument()->UpdateAllViews(NULL, 0, pItem);
		}
	}
	CATCH_ALL(e)
	{
		// cleanup item, if allocated
		if (pItem != NULL)
			GetDocument()->DeleteItem(pItem);
		AfxMessageBox(IDP_FAILED_TO_CREATE);
		return;
	}
	END_CATCH_ALL
}

void CMainView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
	// determine if private or standard OLE formats are on the clipboard
	COleDataObject dataObj;
	BOOL bEnable = dataObj.AttachClipboard() &&
		(dataObj.IsDataAvailable(CMainDoc::m_cfPrivate) ||
		 COleClientItem::CanCreateFromData(&dataObj));

	// enable command based on availability
	pCmdUI->Enable(bEnable);
}

void CMainView::OnObjectResetsize()
{
	ASSERT(m_pSelection != NULL);
	m_pSelection->ResetSize();
}

void CMainView::OnCancelInplace()
{
	// deactivate the inplace active item on this frame/view
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL)
		pActiveItem->Deactivate();
	ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}

void CMainView::OnDestroy()
{
	CScrollView::OnDestroy();

	// deactivate the inplace active item on this view
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
	{
		pActiveItem->Deactivate();
		ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
	}
}

void CMainView::OnUpdateOleEditProperties(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_pSelection != NULL);
}

// edit properties dialog specific to OCLIENT
class COlePropertiesEx : public COlePropertiesDialog
{
public:
	COlePropertiesEx(COleClientItem* pItem,
		UINT nScaleMin = 10, UINT nScaleMax = 500, CWnd* pParentWnd = NULL)
		: COlePropertiesDialog(pItem, nScaleMin, nScaleMax, pParentWnd)
		{ }

	virtual BOOL OnApplyScale(
		COleClientItem* pItem, int nCurrentScale, BOOL bRelativeToOrig);
};

BOOL COlePropertiesEx::OnApplyScale(
	COleClientItem* pItem, int nCurrentScale, BOOL bRelativeToOrig)
{
	if (nCurrentScale != -1)
	{
		ASSERT_VALID(pItem);
		CRectItem* pRectItem = (CRectItem*)pItem;
		ASSERT_KINDOF(CRectItem, pRectItem);

		// reset to original size if necessary
		if (bRelativeToOrig)
			pRectItem->ResetSize();

		// update extent to reflect scaling factor
		pRectItem->Invalidate();
		CSize size = pRectItem->GetSize();
		size.cx = MulDiv(size.cx, nCurrentScale, 100);
		size.cy = MulDiv(size.cy, nCurrentScale, 100);
		pRectItem->SetSize(size);
		pRectItem->Invalidate();
	}
	return TRUE;
}

void CMainView::OnOleEditProperties()
{
	ASSERT(m_pSelection != NULL);

	COlePropertiesEx dlg(m_pSelection);
	dlg.DoModal();
}

void CMainView::OnUpdateOleChangeSource(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(m_pSelection != NULL && m_pSelection->GetType() == OT_LINK);
}

void CMainView::OnOleChangeSource()
{
	ASSERT(m_pSelection != NULL && m_pSelection->GetType() == OT_LINK);

	COleChangeSourceDialog dlg(m_pSelection);
	dlg.DoModal();
}

⌨️ 快捷键说明

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