📄 figure.cpp
字号:
/*
* FIGURE.CPP
* Cosmo Chapter 23
*
* Implementation of the CFigure object for Cosmo.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "cosmo.h"
/*
* CFigure::CFigure
* CFigure::~CFigure
*
* Parameters (Constructor):
* pfnDestroy PFNDESTROYED to call when object is destroyed.
* pDoc PCCosmoDoc we're associated with.
*/
CFigure::CFigure(PFNDESTROYED pfnDestroy, PCCosmoDoc pDoc)
{
m_cRef=0;
m_pfnDestroy=pfnDestroy;
m_pFR=NULL; //We get this later through FrameSet.
m_pDoc=pDoc;
m_pPL=pDoc->m_pPL;
m_fEmbedded=FALSE;
//NULL any contained interfaces initially.
m_pImpIPersistStorage=NULL;
m_pIStorage=NULL;
m_pIStream=NULL;
m_pImpIDataObject=NULL;
m_pIDataAdviseHolder=NULL;
m_pImpIOleObject=NULL;
m_pIOleAdviseHolder=NULL;
m_pIOleClientSite=NULL;
m_clsID=CLSID_CosmoFigure;
m_cf=pDoc->m_cf;
//These are for IDataObject::QueryGetData
m_cfeGet=CFORMATETCGET;
SETDefFormatEtc(m_rgfeGet[0], pDoc->m_cf, TYMED_HGLOBAL);
SETDefFormatEtc(m_rgfeGet[1], pDoc->m_cfEmbedSource
, TYMED_ISTORAGE);
SETDefFormatEtc(m_rgfeGet[2], pDoc->m_cfObjectDescriptor
, TYMED_HGLOBAL);
SETDefFormatEtc(m_rgfeGet[3], CF_METAFILEPICT, TYMED_MFPICT);
SETDefFormatEtc(m_rgfeGet[4], CF_BITMAP, TYMED_GDI);
m_pST=NULL;
m_pImpIPersistFile=NULL;
//We live in the document's lifetime, so no need to AddRef here.
m_pMoniker=m_pDoc->m_pMoniker;
m_dwRegROT=0L;
//CHAPTER23MOD
m_pIOleIPSite=NULL;
m_pIOleIPFrame=NULL;
m_pIOleIPUIWindow=NULL;
m_pImpIOleIPObject=NULL;
m_pImpIOleIPActiveObject=NULL;
m_hMenuShared=NULL;
m_hOLEMenu=NULL;
m_hAccel=NULL;
m_pHW=NULL;
m_pTB=NULL;
m_cyBar=0;
m_fUndoDeactivates=FALSE;
m_fAllowInPlace=TRUE;
m_fForceSave=FALSE;
//End CHAPTER23MOD
return;
}
CFigure::~CFigure(void)
{
ReleaseInterface(m_pIOleClientSite);
ReleaseInterface(m_pIDataAdviseHolder);
ReleaseInterface(m_pIOleAdviseHolder);
//CHAPTER23MOD
if (NULL!=m_pHW)
delete m_pHW;
if (NULL!=m_pST)
delete m_pST;
/*
* Free contained interfaces.
* Container in-place interfaces released during deactivation.
*/
if (NULL!=m_pTB) //Safety-net
delete m_pTB;
DeleteInterfaceImp(m_pImpIOleIPObject);
DeleteInterfaceImp(m_pImpIOleIPActiveObject);
//End CHAPTER23MOD
//Make sure no one thinks we're still running
if (0L!=m_dwRegROT)
INOLE_RevokeAsRunning(&m_dwRegROT);
ReleaseInterface(m_pIStorage)
ReleaseInterface(m_pIStream)
DeleteInterfaceImp(m_pImpIPersistFile);
DeleteInterfaceImp(m_pImpIOleObject)
DeleteInterfaceImp(m_pImpIDataObject)
DeleteInterfaceImp(m_pImpIPersistStorage);
//Free strings.
if (NULL!=m_pST)
delete m_pST;
return;
}
/*
* CFigure::QueryInterface
* CFigure::AddRef
* CFigure::Release
*
* Purpose:
* IUnknown members for CFigure object.
*/
STDMETHODIMP CFigure::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid)
*ppv=this;
if (IID_IPersist==riid || IID_IPersistStorage==riid)
*ppv=m_pImpIPersistStorage;
if (IID_IDataObject==riid)
*ppv=m_pImpIDataObject;
if (IID_IOleObject==riid)
*ppv=m_pImpIOleObject;
if (IID_IPersistFile==riid)
*ppv=m_pImpIPersistFile;
//CHAPTER23MOD
if (IID_IOleWindow==riid || IID_IOleInPlaceObject==riid)
*ppv=m_pImpIOleIPObject;
//End CHAPTER23MOD
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CFigure::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CFigure::Release(void)
{
if (0!=--m_cRef)
return m_cRef;
if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();
//Document deletes us
return 0;
}
/*
* CFigure::Init
*
* Purpose:
* Performs any initialization of a CFigure that's prone to failure
* that we also use internally before exposing the object outside.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the function is successful,
* FALSE otherwise.
*/
BOOL CFigure::Init(void)
{
m_pST=new CStringTable(m_pDoc->m_hInst);
if (NULL==m_pST)
return FALSE;
if (!m_pST->Init(IDS_FIGUREMIN, IDS_FIGUREMAX))
return FALSE;
//Allocate contained interfaces.
m_pImpIPersistStorage=new CImpIPersistStorage(this, this);
if (NULL==m_pImpIPersistStorage)
return FALSE;
m_pImpIDataObject=new CImpIDataObject(this, this);
if (NULL==m_pImpIDataObject)
return FALSE;
m_pImpIOleObject=new CImpIOleObject(this, this);
if (NULL==m_pImpIOleObject)
return FALSE;
m_pImpIPersistFile=new CImpIPersistFile(this, this);
if (NULL==m_pImpIPersistFile)
return FALSE;
//CHAPTER23MOD
m_pImpIOleIPObject=new CImpIOleInPlaceObject(this, this);
if (NULL==m_pImpIOleIPObject)
return FALSE;
m_pImpIOleIPActiveObject=new CImpIOleInPlaceActiveObject(this
, this);
if (NULL==m_pImpIOleIPActiveObject)
return FALSE;
m_pHW=new CHatchWin(m_pDoc->m_hInst);
if (NULL==m_pHW)
return FALSE;
//We don't have m_pFR yet from which to get the frame window.
if (!m_pHW->Init(m_pDoc->Window(), ID_HATCHWINDOW, NULL))
return FALSE;
//End CHAPTER23MOD
return TRUE;
}
/*
* CFigure::FrameSet
*
* Purpose:
* Provides the compound document object with access to the frame
* of this application for UI purposes.
*
* Parameters:
* pFR PCCosmoFrame of the frame window.
*
* Return Value:
* None
*/
void CFigure::FrameSet(PCCosmoFrame pFR)
{
m_pFR=pFR;
//CHAPTER23MOD
//We need this in IOleInPlaceActiveObject::ResizeBorder
m_cyBar=m_pFR->m_cyBar;
//We need this in IOleInPlaceActiveObject::TranslateAccelerator
m_hAccel=m_pFR->m_hAccel;
//End CHAPTER23MOD
return;
}
/*
* CFigure::FIsDirty
*
* Purpose:
* Checks if the document is dirty. This can be called from
* IPersistStorage::IsDirty which doesn't have access to CCosmoDoc.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if dirty, FALSE if clean.
*/
BOOL CFigure::FIsDirty(void)
{
//CHAPTER23MOD
//Force a save if we opened after being in-place.
return m_pDoc->m_fDirty || m_fForceSave;
//End CHAPTER23MOD
}
/*
* CFigure::FIsEmbedded
*
* Purpose:
* Answers if the object is embedded or not.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the object is embedded, FALSE otherwise.
*/
BOOL CFigure::FIsEmbedded(void)
{
return m_fEmbedded;
}
/*
* CFigure::SendAdvise
*
* Purpose:
* Calls the appropriate IOleClientSite or IAdviseSink member
* function for various events such as closure, saving, etc.
*
* Parameters:
* uCode UINT OBJECTCODE_* identifying the notification.
*
* Return Value:
* None
*/
void CFigure::SendAdvise(UINT uCode)
{
switch (uCode)
{
case OBJECTCODE_SAVED:
if (NULL!=m_pIOleAdviseHolder)
m_pIOleAdviseHolder->SendOnSave();
break;
case OBJECTCODE_CLOSED:
if (NULL!=m_pIOleAdviseHolder)
m_pIOleAdviseHolder->SendOnClose();
break;
case OBJECTCODE_RENAMED:
m_pMoniker=m_pDoc->m_pMoniker; //For IOleObject::GetMoniker
m_dwRegROT=m_pDoc->m_dwRegROT;
if (NULL!=m_pIOleAdviseHolder)
m_pIOleAdviseHolder->SendOnRename(m_pMoniker);
break;
case OBJECTCODE_SAVEOBJECT:
if (FIsDirty() && NULL!=m_pIOleClientSite)
m_pIOleClientSite->SaveObject();
break;
case OBJECTCODE_DATACHANGED:
//No flags are necessary here.
if (NULL!=m_pIDataAdviseHolder)
{
m_pIDataAdviseHolder->SendOnDataChange
(m_pImpIDataObject, 0, 0);
}
//Tell the running object table of the change
if (0!=m_dwRegROT)
INOLE_NoteChangeTime(m_dwRegROT, NULL, NULL);
//CHAPTER23MOD
/*
* If this is the first change after activation, tell the
* container to free any undo information it's holding.
*/
if (NULL!=m_pIOleIPSite && m_fUndoDeactivates)
m_pIOleIPSite->DiscardUndoState();
m_fUndoDeactivates=FALSE;
//End CHAPTER23MOD
break;
case OBJECTCODE_SHOWWINDOW:
if (NULL!=m_pIOleClientSite)
m_pIOleClientSite->OnShowWindow(TRUE);
break;
case OBJECTCODE_HIDEWINDOW:
if (NULL!=m_pIOleClientSite)
m_pIOleClientSite->OnShowWindow(FALSE);
break;
case OBJECTCODE_SHOWOBJECT:
if (NULL!=m_pIOleClientSite)
m_pIOleClientSite->ShowObject();
break;
}
return;
}
//CHAPTER23MOD
/*
* CFigure::InPlaceActivate
*
* Purpose:
* Goes through all the steps of activating the Figure as an
* in-place object.
*
* Parameters:
* pActiveSite LPOLECLIENTSITE of the active site we show in.
* fIncludeUI BOOL indicating if we should do UI as well.
*
* Return Value:
* HRESULT Whatever error code is appropriate.
*/
HRESULT CFigure::InPlaceActivate(LPOLECLIENTSITE pActiveSite
, BOOL fIncludeUI)
{
HRESULT hr;
HWND hWnd, hWndHW;
RECT rcPos;
RECT rcClip;
if (NULL==pActiveSite)
return ResultFromScode(E_INVALIDARG);
//If we're already active, do the UI and we're done.
if (NULL!=m_pIOleIPSite)
{
if (fIncludeUI)
UIActivate();
return NOERROR;
}
/*
* 1. Initialization, obtaining interfaces, calling
* OnInPlaceActivate.
*/
hr=pActiveSite->QueryInterface(IID_IOleInPlaceSite
, (PPVOID)&m_pIOleIPSite);
if (FAILED(hr))
return hr;
hr=m_pIOleIPSite->CanInPlaceActivate();
if (NOERROR!=hr)
{
m_pIOleIPSite->Release();
m_pIOleIPSite=NULL;
return ResultFromScode(E_FAIL);
}
m_pIOleIPSite->OnInPlaceActivate();
m_fUndoDeactivates=TRUE;
/*
* 2. Get the window context and create a window or change the
* parent and position of an existing window. Servers are
* required to full cb in the OLEINPLACEFRAMEINFO structure.
*/
m_pIOleIPSite->GetWindow(&hWnd);
m_pFR->m_frameInfo.cb=sizeof(OLEINPLACEFRAMEINFO);
m_pIOleIPSite->GetWindowContext(&m_pIOleIPFrame
, &m_pIOleIPUIWindow, &rcPos, &rcClip
, &m_pFR->m_frameInfo);
/*
* Copy container frame pointer to CCosmoFrame for accelerators.
* No AddRef because frame never messes with it. Note also that
* we don't do anything special with our own accelerators here
* because we just use the same ones as always.
*/
m_pFR->m_pIOleIPFrame=m_pIOleIPFrame;
/*
* We'll use a hatch window as the child of the container and the
* editing window as a child of the hatch window. We already
* created the hatch window, so now all we have to do is put it
* in the right place and stick the Polyline in it.
*/
m_pHW->HwndAssociateSet(m_pFR->Window());
m_pHW->ChildSet(m_pPL->Window()); //Calls SetParent
m_pHW->RectsSet(&rcPos, &rcClip); //Positions polyline
hWndHW=m_pHW->Window();
SetParent(hWndHW, hWnd); //Move the hatch window
ShowWindow(hWndHW, SW_SHOW); //Make us visible.
SendAdvise(OBJECTCODE_SHOWOBJECT);
if (fIncludeUI)
return UIActivate();
return NOERROR;
}
/*
* CFigure::InPlaceDeactivate
*
* Purpose:
* Reverses all the activation steps from InPlaceActivate.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CFigure::InPlaceDeactivate(void)
{
RECT rc;
UIDeactivate();
/*
* When setting the parent back to the normal document,
* reposition the Polyline to be at (8,8) instead of at wherever
* it was in the container's window or our hatch window. This
* is so if we are deactivating to open in our own window the
* Polyline appears in the proper place in the document window.
*/
SetParent(m_pPL->Window(), m_pDoc->m_hWnd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -