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

📄 mainview.cpp

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

	ar.Close();
	delete pFile;

	// adjust position to that specified by point
	if (pPoint != NULL)
		pItem->m_ptPos = *pPoint;
}

void CMainView::DoPasteStandard(BOOL bLink, COleDataObject* pDataObject,
	CPoint* pPoint, CRectItem* pItem, CLIPFORMAT cfFormat)
{
	if (bLink)      // paste link
	{
		if (!pItem->CreateLinkFromData(pDataObject))
			AfxThrowMemoryException();  // any exception will do
	}
	// paste embedded
	else if (!pItem->CreateFromData(pDataObject) &&
		!pItem->CreateStaticFromData(pDataObject, OLERENDER_DRAW, cfFormat))
	{
		AfxThrowMemoryException();      // any exception will do
	}

	// copy the current iconic representation
	FORMATETC fmtetc;
	fmtetc.cfFormat = CF_METAFILEPICT;
	fmtetc.dwAspect = DVASPECT_ICON;
	fmtetc.ptd = NULL;
	fmtetc.tymed = TYMED_MFPICT;
	fmtetc.lindex = 1;
	HGLOBAL hObj = pDataObject->GetGlobalData(CF_METAFILEPICT, &fmtetc);
	if (hObj != NULL)
	{
		pItem->SetIconicMetafile(hObj);
		// the following code is an easy way to free a metafile pict
		STGMEDIUM stgMed;
		memset(&stgMed, 0, sizeof(stgMed));
		stgMed.tymed = TYMED_MFPICT;
		stgMed.hGlobal = hObj;
		ReleaseStgMedium(&stgMed);
	}

	// set the current drawing aspect
	hObj = pDataObject->GetGlobalData(m_cfObjectDescriptor);
	if (hObj != NULL)
	{
		ASSERT(hObj != NULL);
		// got CF_OBJECTDESCRIPTOR ok.  Lock it down and extract size.
		LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR)GlobalLock(hObj);
		ASSERT(pObjDesc != NULL);
		pItem->SetDrawAspect((DVASPECT)pObjDesc->dwDrawAspect);
		GlobalUnlock(hObj);
		GlobalFree(hObj);
	}

	// set top-left based on point of drop
	if (pPoint != NULL)
		pItem->m_ptPos = *pPoint;

	// get size from drag/drop operation
	CSize size;
	if (GetObjectInfo(pDataObject, &size, NULL) && size.cx != 0 && size.cy != 0)
	{
		// use size obtained from object instead of default
		size.cx = MulDiv(size.cx, 10, 254);
		size.cy = -MulDiv(size.cy, 10, 254);
		pItem->SetSize(size);
		CSize sizeExtent;
		pItem->GetCachedExtent(&sizeExtent);
		pItem->SetBaseSize(sizeExtent);
	}
	else
	{
		// no extent from CF_OBJECTDESCRIPTOR, use extent from object
		pItem->UpdateExtent();
	}
}


// Helper for paste/pastelink
//
//                  bLink       pDataObject     pPoint              cfFormat
//  EditPaste       FALSE       NULL(clipboard) NULL(default)       0
//  Drag/Drop       TRUE/FALSE  X               X                   0
//  PasteLink       TRUE        NULL(clipboard) NULL(default)       0
//  PasteSpecial    TRUE/FALSE  X               NULL(default)       X
CRectItem* CMainView::DoPasteItem(BOOL bLink, COleDataObject* pDataObject,
	CPoint* pPoint, CLIPFORMAT cfFormat)
{
	BeginWaitCursor();

	CRectItem* pItem = GetDocument()->CreateItem();
	ASSERT_VALID(pItem);
	BOOL bAllowAdjust = (pPoint == NULL) ? TRUE : FALSE;

	// use clipboard data if not doing drag/drop
	COleDataObject clipboardData;
	if (pDataObject == NULL)
	{
		clipboardData.AttachClipboard();
		pDataObject = &clipboardData;
	}

	TRY
	{
		if (cfFormat == CMainDoc::m_cfPrivate)
		{
			// if format specified (i.e. PasteSpecial) then use that one
			DoPasteNative(pDataObject, pPoint, pItem);
		}
		else if (!bLink && cfFormat == 0 &&
			pDataObject->IsDataAvailable(CMainDoc::m_cfPrivate))
		{
			// if we're not pasting a link, cfFormat was unspecified,
			// and private format is available use it
			DoPasteNative(pDataObject, pPoint, pItem);
		}
		// otherwise perform a standard paste
		else if (bAllowAdjust)
		{
			CPoint ptDef(10, -10);
			DoPasteStandard(bLink, pDataObject, &ptDef, pItem, cfFormat);
		}
		else
		{
			DoPasteStandard(bLink, pDataObject, pPoint, pItem, cfFormat);
		}

		if (bAllowAdjust)
		{
			// allow document to adjust position of item so that it doesn't
			// lay directly over an item of the same size
			// this only occurs if the drop point is not specified
			GetDocument()->AdjustItemPosition(pItem);
		}
	}
	CATCH_ALL(e)
	{
		// general cleanup
		TRACE0("failed to embed/link an OLE object\n");
		pItem->Delete();
		pItem = NULL;
	}
	END_CATCH_ALL

	// set the selection with bSafeSelect = TRUE
	SetSelection(pItem, TRUE);

	// update the document and views
	GetDocument()->SetModifiedFlag();
	GetDocument()->UpdateAllViews(NULL, 0, pItem);      // including this view

	EndWaitCursor();

	return pItem;
}

/////////////////////////////////////////////////////////////////////////////
// Insert New Object and Activate Object

void CMainView::OnInsertObject()
{
	COleInsertDialog dlg;
	if (dlg.DoModal() != IDOK)
		return;

	BeginWaitCursor();

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

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

		// if insert new object -- initially show the object
		if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
			pItem->DoVerb(OLEIVERB_SHOW, this);

		SetSelection(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::OnLButtonDblClk(UINT, CPoint)
{
	// Double click will activate the main verb
	if (m_pSelection != NULL)
	{
		BeginWaitCursor();
		LONG iVerb = OLEIVERB_PRIMARY;
		if (GetKeyState(VK_CONTROL) < 0)
			iVerb = OLEIVERB_OPEN;
		m_pSelection->DoVerb(iVerb, this);
		EndWaitCursor();
	}
}

/////////////////////////////////////////////////////////////////////////////
// Hit detection, moving and resizing items

CRectItem* CMainView::GetHitItem(CPoint point)
{
	CMainDoc* pDoc = GetDocument();
	CRectItem* pItemHit = NULL;

	// Find the item hit by the mouse
	POSITION pos = pDoc->GetStartPosition();
	while (pos != NULL)
	{
		CRectItem* pItem = DYNAMIC_DOWNCAST(CRectItem, pDoc->GetNextItem(pos));
		if (pItem != NULL)
		{
			CRectTracker tracker;
			SetupTracker(&tracker, pItem);
			if (tracker.HitTest(point) >= 0)
			{
				pItemHit = pItem;
				// items later in the list are drawn on top - so keep looking
			}
		}
	}
	return pItemHit;
}

void CMainView::DocToClient(CRect& rect)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.LPtoDP(&rect); // convert logical rect to device rect
	rect.NormalizeRect();
}

void CMainView::ClientToDoc(CRect& rect)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&rect); // convert device rect to logical rect
}

void CMainView::DocToClient(CSize& size)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.LPtoDP(&size); // convert logical size to device size
	size.cx = abs(size.cx);
	size.cy = abs(size.cy);
}

void CMainView::ClientToDoc(CSize& size)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&size); // convert device rect to logical rect
	size.cx = abs(size.cx);
	size.cy = abs(size.cy);
}

void CMainView::DocToClient(CPoint& point)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.LPtoDP(&point); // convert logical point to device point
}

void CMainView::ClientToDoc(CPoint& point)
{
	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&point); // convert device point to logical point
}

void CMainView::OnLButtonDown(UINT /*nFlags*/, CPoint point)
{
	CRectItem* pItemHit = GetHitItem(point);
	SetSelection(pItemHit);
	if (pItemHit == NULL)
		return;

	CRect rectLimit;
	GetClientRect(rectLimit);

	CRectTracker tracker;
	SetupTracker(&tracker, pItemHit);

	UpdateWindow(); // update before entering the tracker
	if (tracker.HitTest(point) == CRectTracker::hitMiddle) // moving, not sizing
	{
		// determine mouse position offset from the item itself
		CRect rect = pItemHit->GetRect();
		DocToClient(rect);
		CPoint ptOffset(point.x - rect.left, point.y - rect.top);

		// determine sensitivity rectangle (determines when drag starts)
		CRect rectDrag(rect.left, rect.top, rect.left+1, rect.top+1);

		// execute the drag/drop operation
		m_bInDrag = TRUE;
		ClientToScreen(&rect);  // must be in screen co-ordinates
		ClientToScreen(&rectDrag);
		DROPEFFECT dropEffect = pItemHit->DoDragDrop(rect, ptOffset,
			TRUE, DROPEFFECT_COPY|DROPEFFECT_MOVE, &rectDrag);
		if (m_bInDrag == FALSE) // move in same window
			return;
		m_bInDrag = FALSE;

		if (dropEffect == DROPEFFECT_MOVE)
		{
			// the item was moved (essentially a copy w/delete)
			pItemHit->Invalidate();
			if (m_pSelection == pItemHit)
				m_pSelection = NULL;
			GetDocument()->DeleteItem(pItemHit);
		}
	}
	else if (tracker.Track(this, point))
	{
		ClientToDoc(tracker.m_rect);
		pItemHit->Move(tracker.m_rect);
		GetDocument()->SetModifiedFlag();
	}
}

BOOL CMainView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	if (pWnd == this && m_pSelection != NULL)
	{
		// give the tracker for the selection a chance
		CRectTracker tracker;
		SetupTracker(&tracker, m_pSelection);
		if (tracker.SetCursor(this, nHitTest))
			return TRUE;
	}
	return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

/////////////////////////////////////////////////////////////////////////////
// Right mouse for popup context sensitive menu

void CMainView::OnRButtonDown(UINT, CPoint point)
{
	// make sure window is active
	GetParentFrame()->ActivateFrame();

	SetSelection(GetHitItem(point));    // reselect item if appropriate
	UpdateWindow();

	if (m_pSelection != NULL)
	{
		CMenu bar;
		if (bar.LoadMenu(ID_OBJECT_POPUP_MENU))
		{
			CMenu& popup = *bar.GetSubMenu(0);
			ASSERT(popup.m_hMenu != NULL);

			ClientToScreen(&point);
			popup.TrackPopupMenu(TPM_RIGHTBUTTON,
				point.x, point.y,
				AfxGetMainWnd()); // route commands through main window
		}
	}
}

void CMainView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	MessageBeep(0);     // to test for proper focus transfer

	CScrollView::OnChar(nChar, nRepCnt, nFlags);
}

void CMainView::OnSetFocus(CWnd* pOldWnd)
{
	COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
	if (pActiveItem != NULL &&
		pActiveItem->GetItemState() == COleClientItem::activeUIState)
	{
		// need to set focus to this item if it is in the same view
		CWnd* pWnd = pActiveItem->GetInPlaceWindow();
		if (pWnd != NULL)
		{
			pWnd->SetFocus();
			return;
		}
	}

	CScrollView::OnSetFocus(pOldWnd);
}

void CMainView::OnSize(UINT nType, int cx, int cy)
{
	CScrollView::OnSize(nType, cx, cy);

	UpdateActiveItem();
}

/////////////////////////////////////////////////////////////////////////////
// support for drag/drop

int CMainView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CScrollView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// register drop target
	m_dropTarget.Register(this);

	return 0;
}

⌨️ 快捷键说明

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