📄 olecli3.cpp
字号:
// 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_OLE_SEG
#pragma code_seg(AFX_OLE_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// COleClientItem activation
// helper to get client site -- this is called from a number of places
LPOLECLIENTSITE COleClientItem::GetClientSite()
{
ASSERT_VALID(this);
LPOLECLIENTSITE lpClientSite =
(LPOLECLIENTSITE)GetInterface(&IID_IOleClientSite);
ASSERT(lpClientSite != NULL);
return lpClientSite;
}
void COleClientItem::Activate(LONG nVerb, CView* pView, LPMSG lpMsg)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
if (pView != NULL)
ASSERT_VALID(pView);
if (lpMsg != NULL)
ASSERT(AfxIsValidAddress(lpMsg, sizeof(MSG), FALSE));
// store the container HWND for in place activation then do the verb
if (m_pView == NULL)
m_pView = pView;
_AFX_OLE_STATE* pOleState = _afxOleState;
CView* pViewSave = pOleState->m_pActivateView;
pOleState->m_pActivateView = NULL;
// get item rectangle for in-place players
// (that may not support in-place activation)
LPCRECT lpPosRect = NULL;
CRect rectPos;
if (pView != NULL)
{
ASSERT_VALID(pView);
rectPos.SetRectEmpty();
OnGetItemPosition(rectPos);
if (!rectPos.IsRectEmpty())
{
lpPosRect = &rectPos;
pOleState->m_pActivateView = pView;
}
}
// prepare DoVerb parameters and call into the server
LPOLECLIENTSITE lpClientSite = GetClientSite();
HWND hWnd = pView->GetSafeHwnd();
SCODE sc = m_lpObject->DoVerb(nVerb, lpMsg, lpClientSite, -1,
hWnd, lpPosRect);
pOleState->m_pActivateView = pViewSave;
// clear out m_pView in case in-place activation only partially worked
if (!IsInPlaceActive())
m_pView = NULL;
// update available status based on the results of DoVerb
// (this is used in the links dialog).
m_bLinkUnavail = (BYTE)FAILED(sc);
CheckGeneral(sc);
}
//////////////////////////////////////////////////////////////////////////////
// Create error handling
void COleClientItem::CheckGeneral(SCODE sc)
// set 'm_scLast'
// throw exception if not ok to continue
{
ASSERT_VALID(this);
m_scLast = S_OK; // assume things are ok
// then, check for error
if (sc != S_OK)
{
m_scLast = sc;
if (!FAILED(sc))
{
#ifdef _DEBUG
// warn about non-NULL success codes
TRACE1("Warning: operation returned scode = %s.\n",
AfxGetFullScodeString(m_scLast));
#endif
return;
}
// this error wasn't expected, so throw an exception
AfxThrowOleException(sc);
}
}
/////////////////////////////////////////////////////////////////////////////
// COleClientItem clipboard support
void COleClientItem::CopyToClipboard(BOOL bIncludeLink)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
// get clipboard data for this item
COleDataSource* pDataSource = OnGetClipboardData(bIncludeLink, NULL, NULL);
TRY
{
// put it on the clipboard
pDataSource->SetClipboard();
}
CATCH_ALL(e)
{
delete pDataSource;
THROW_LAST();
}
END_CATCH_ALL
}
COleDataSource* COleClientItem::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 COleClientItem::DoDragDrop(LPCRECT lpItemRect, CPoint ptOffset,
BOOL bIncludeLink, DWORD dwEffects, LPCRECT lpRectStartDrag)
{
ASSERT(AfxIsValidAddress(lpItemRect, sizeof(RECT)));
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
DROPEFFECT dropEffect = DROPEFFECT_NONE;
COleDataSource *pDataSource = NULL;
TRY
{
// get clipboard data object for the item
CSize sizeItem(
lpItemRect->right - lpItemRect->left,
lpItemRect->bottom - lpItemRect->top);
pDataSource = OnGetClipboardData(bIncludeLink, &ptOffset, &sizeItem);
// add DROPEFFECT_LINK only 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;
if (lpRectStartDrag == NULL)
{
rectDrag.SetRect(lpItemRect->left, lpItemRect->bottom,
lpItemRect->left, lpItemRect->bottom);
lpRectStartDrag = &rectDrag;
}
// do drag drop operation
dropEffect = pDataSource->DoDragDrop(dwEffects, lpRectStartDrag);
pDataSource->InternalRelease();
}
CATCH_ALL(e)
{
if (pDataSource != NULL)
pDataSource->InternalRelease();
THROW_LAST();
}
END_CATCH_ALL
return dropEffect;
}
void COleClientItem::GetClipboardData(COleDataSource* pDataSource,
BOOL bIncludeLink, LPPOINT lpOffset, LPSIZE lpSize)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
ASSERT_VALID(pDataSource);
// add CF_EMBEDDEDOBJECT by creating memory storage copy of the object
STGMEDIUM stgMedium;
GetEmbeddedItemData(&stgMedium);
pDataSource->CacheData((CLIPFORMAT)_oleData.cfEmbeddedObject, &stgMedium);
// add CF_OBJECTDESCRIPTOR
GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
pDataSource->CacheData((CLIPFORMAT)_oleData.cfObjectDescriptor,
&stgMedium);
// add any presentation entries in the object's cache
AddCachedData(pDataSource);
// add CF_LINKSOURCE if supporting links to embeddings
if (bIncludeLink && GetLinkSourceData(&stgMedium))
{
pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSource, &stgMedium);
// add CF_LINKSOURCEDESCRIPTOR
GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSourceDescriptor,
&stgMedium);
}
}
BOOL PASCAL COleClientItem::CanPaste()
{
// it is faster and more reliable to use the Windows clipboard
// APIs instead of OleQueryCreateFromData.
return IsClipboardFormatAvailable(_oleData.cfEmbedSource) ||
IsClipboardFormatAvailable(_oleData.cfEmbeddedObject) ||
IsClipboardFormatAvailable(_oleData.cfFileName) ||
IsClipboardFormatAvailable(_oleData.cfFileNameW) ||
IsClipboardFormatAvailable(CF_METAFILEPICT) ||
IsClipboardFormatAvailable(CF_DIB) ||
IsClipboardFormatAvailable(CF_BITMAP) ||
(IsClipboardFormatAvailable(_oleData.cfOwnerLink) &&
IsClipboardFormatAvailable(_oleData.cfNative));
}
BOOL PASCAL COleClientItem::CanPasteLink()
{
// it is faster and more reliable to use the Windows clipboard
// APIs instead of OleQueryCreateFromData.
return IsClipboardFormatAvailable(_oleData.cfLinkSource) ||
IsClipboardFormatAvailable(_oleData.cfFileName) ||
IsClipboardFormatAvailable(_oleData.cfFileNameW) ||
IsClipboardFormatAvailable(_oleData.cfObjectLink);
}
BOOL PASCAL
COleClientItem::CanCreateFromData(const COleDataObject* pDataObject)
{
if (pDataObject->m_bClipboard)
return COleClientItem::CanPaste();
((COleDataObject*)pDataObject)->EnsureClipboardObject();
if (pDataObject->m_lpDataObject == NULL)
return FALSE;
SCODE sc = ::OleQueryCreateFromData(pDataObject->m_lpDataObject);
return !FAILED(sc) && sc != S_FALSE;
}
BOOL PASCAL
COleClientItem::CanCreateLinkFromData(const COleDataObject* pDataObject)
{
if (pDataObject->m_bClipboard)
return COleClientItem::CanPasteLink();
((COleDataObject*)pDataObject)->EnsureClipboardObject();
if (pDataObject->m_lpDataObject == NULL)
return FALSE;
SCODE sc = ::OleQueryLinkFromData(pDataObject->m_lpDataObject);
return !FAILED(sc) && sc != S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Conversion & Activate As support
BOOL COleClientItem::ConvertTo(REFCLSID clsidNew)
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);
// first, close the object
Close();
// convert it
m_scLast = _AfxOleDoConvert(m_lpStorage, clsidNew);
if (FAILED(m_scLast))
return FALSE;
// save IOleObject and IViewObject2 pointers
LPOLEOBJECT lpObject = m_lpObject;
LPVIEWOBJECT2 lpViewObject = m_lpViewObject;
DWORD dwConnection = m_dwConnection;
// NULL out IOleObject and IViewObject2 cached pointers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -