📄 mainview.cpp
字号:
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 + -