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