?? tenant.cpp
字號:
/*
* TENANT.CPP
* Patron Chapter 17
*
* Implementation of the CTentant class which holds information
* for a single object on a page. It maintains position, references
* to data, and a storage.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
/*
* CTenant::CTenant
* CTenant::~CTenant
*
* Constructor Parameters:
* dwID DWORD identifier for this page.
* hWnd HWND of the pages window.
* pPG PCPages to the parent structure.
*/
CTenant::CTenant(DWORD dwID, HWND hWnd, PCPages pPG)
{
m_hWnd=hWnd;
m_dwID=dwID;
m_fInitialized=0;
m_pIStorage=NULL;
m_cOpens=0;
m_pObj=NULL;
m_pPG =pPG;
m_clsID=CLSID_NULL;
m_fSetExtent=FALSE;
//CHAPTER17MOD
m_cRef=0;
m_pIOleObject=NULL;
m_pIViewObject2=NULL;
m_grfMisc=0;
m_pImpIOleClientSite=NULL;
m_pImpIAdviseSink=NULL;
m_fRepaintEnabled=TRUE;
//End CHAPTER17MOD
return;
}
CTenant::~CTenant(void)
{
//CHAPTER17MOD
//Object pointers cleaned up in Close.
DeleteInterfaceImp(m_pImpIAdviseSink);
DeleteInterfaceImp(m_pImpIOleClientSite);
//End CHAPTER17MOD
return;
}
//CHAPTER17MOD
/*
* CTenant::QueryInterface
* CTenant::AddRef
* CTenant::Release
*
* Purpose:
* IUnknown members for CTenant object.
*/
STDMETHODIMP CTenant::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid)
*ppv=this;
if (IID_IOleClientSite==riid)
*ppv=m_pImpIOleClientSite;
if (IID_IAdviseSink==riid)
*ppv=m_pImpIAdviseSink;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CTenant::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CTenant::Release(void)
{
if (0!=--m_cRef)
return m_cRef;
delete this;
return 0;
}
//End CHAPTER17MOD
/*
* CTenant::GetID
*
* Return Value:
* DWORD dwID field in this tenant.
*/
DWORD CTenant::GetID(void)
{
return m_dwID;
}
/*
* CTenant::GetStorageName
*
* Parameters:
* pszName LPOLESTR to a buffer in which to store the storage
* name for this tenant.
*
* Return Value:
* UINT Number of characters stored.
*/
UINT CTenant::GetStorageName(LPOLESTR pszName)
{
#ifdef WIN32ANSI
char szTemp[32];
UINT cch;
cch=wsprintf(szTemp, "Tenant %lu", m_dwID);
MultiByteToWideChar(CP_ACP, 0, szTemp, -1, pszName, 32);
return cch;
#else
return wsprintf(pszName, TEXT("Tenant %lu"), m_dwID);
#endif
}
//CHAPTER17MOD
/*
* CTenant::StorageGet
*
* Purpose:
* Returns the IStorage pointer maintained by this tenant,
* AddRef'd of course.
*
* Parameters:
* ppStg LPSTORAGE * in which to return the pointer.
*
* Return Value:
* None
*/
void CTenant::StorageGet(LPSTORAGE *ppStg)
{
if (NULL==ppStg)
return;
*ppStg=m_pIStorage;
if (NULL!=*ppStg)
(*ppStg)->AddRef();
return;
}
//End CHAPTER17MOD
/*
* CTenant::Create
*
* Purpose:
* Creates a new tenant of the given CLSID, which can be either a
* static bitmap or metafile or any compound document object.
*
* Parameters:
* tType TENANTTYPE to create, either a static metafile,
* bitmap, or some kind of compound document object
* This determines which OleCreate* call we use.
* pvType LPVOID providing the relevant pointer from which
* to create the tenant, depending on iType.
* pFE LPFORMATETC specifying the type of renderings
* to use.
* pptl PPOINTL in which we store offset coordinates.
* pszl LPSIZEL where this object should store its
* lometric extents.
* pIStorage LPSTORAGE of the page we live in. We have to
* create another storage in this for the tenant.
* ppo PPATRONOBJECT containing placement data.
* dwData DWORD with extra data, sensitive to iType.
*
* Return Value:
* UINT A CREATE_* value depending on what we
* actually do.
*/
UINT CTenant::Create(TENANTTYPE tType, LPVOID pvType
, LPFORMATETC pFE, PPOINTL pptl, LPSIZEL pszl
, LPSTORAGE pIStorage, PPATRONOBJECT ppo, DWORD dwData)
{
HRESULT hr;
LPUNKNOWN pObj;
UINT uRet=CREATE_GRAPHICONLY;
//CHAPTER17MOD
//Some things moves to ObjectInitialize
//End CHAPTER17MOD
if (NULL==pvType || NULL==pIStorage)
return CREATE_FAILED;
//Fail if this is called for an already living tenant.
if (m_fInitialized)
return CREATE_FAILED;
m_fInitialized=TRUE;
//Create a new storage for this tenant.
if (!Open(pIStorage))
return CREATE_FAILED;
/*
* Get the placement info if it's here. We either have a non-
* NULL PPATRONOBJECT in ppo or we have to use default
* placement and retrieve the size from the object itself.
*/
pszl->cx=0;
pszl->cy=0;
if (NULL!=ppo)
{
*pFE=ppo->fe;
*pptl=ppo->ptl;
*pszl=ppo->szl; //Could be 0,0 , so we ask object
uRet=CREATE_PLACEDOBJECT;
}
hr=ResultFromScode(E_FAIL);
//Now create an object based specifically for the type.
switch (tType)
{
case TENANTTYPE_NULL:
break;
case TENANTTYPE_STATIC:
/*
* We could use OleCreateStaticFromData here which does
* pretty much what we're doing below. However, it does
* not allow us to control whether we paste a bitmap or
* a metafile--it uses metafile first, bitmap second.
* For this reason we'll use code developed in Chapter
* 11's FreeLoader to affect the paste.
*/
hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
break;
//CHAPTER17MOD
case TENANTTYPE_EMBEDDEDOBJECT:
hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage
, (PPVOID)&pObj);
break;
case TENANTTYPE_EMBEDDEDFILE:
hr=OleCreateFromFile(CLSID_NULL, (LPTSTR)pvType
, IID_IUnknown, OLERENDER_DRAW, NULL, NULL
, m_pIStorage, (PPVOID)&pObj);
break;
case TENANTTYPE_EMBEDDEDOBJECTFROMDATA:
hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage
, (PPVOID)&pObj);
break;
//End CHAPTER17MOD
default:
break;
}
//If creation didn't work, get rid of the element Open created.
if (FAILED(hr))
{
Destroy(pIStorage);
return CREATE_FAILED;
}
//CHAPTER17MOD
//We don't get the size if PatronObject data was seen already.
if (!ObjectInitialize(pObj, pFE, dwData))
{
Destroy(pIStorage);
return CREATE_FAILED;
}
if (0==pszl->cx && 0==pszl->cy)
{
SIZEL szl;
//Try to get the real size of the object, default to 2"*2"
SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);
hr=ResultFromScode(E_FAIL);
//Try IViewObject2 first, then IOleObject as a backup.
if (NULL!=m_pIViewObject2)
{
hr=m_pIViewObject2->GetExtent(m_fe.dwAspect, -1, NULL
, &szl);
}
else
{
if (NULL!=m_pIOleObject)
hr=m_pIOleObject->GetExtent(m_fe.dwAspect, &szl);
}
if (SUCCEEDED(hr))
{
//Convert HIMETRIC to our LOMETRIC mapping
SETSIZEL((*pszl), szl.cx/10, szl.cy/10);
}
}
//End CHAPTER17MOD
return uRet;
}
/*
* CTenant::Load
*
* Purpose:
* Recreates the object living in this tenant in place of calling
* FCreate. This is used in loading as opposed to new creation.
*
* Parameters:
* pIStorage LPSTORAGE of the page we live in.
* pti PTENTANTINFO containing persistent information.
* The ID value in this structure is ignored.
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CTenant::Load(LPSTORAGE pIStorage, PTENANTINFO pti)
{
HRESULT hr;
LPUNKNOWN pObj;
//CHAPTER17MOD
DWORD dwState=TENANTSTATE_DEFAULT;
//End CHAPTER17MOD
if (NULL==pIStorage || NULL==pti)
return FALSE;
//CHAPTER17MOD
/*
* If we already initialized once, clean up, releasing
* everything before we attempt to reload. This happens
* when using the Convert Dialog.
*/
if (m_fInitialized)
{
//Preserve all states except open
dwState=(m_dwState & ~TENANTSTATE_OPEN);
m_cRef++; //Prevent accidental closure
//This should release all holds on our IStorage as well.
if (NULL!=m_pIViewObject2)
{
m_pIViewObject2->SetAdvise(m_fe.dwAspect, 0, NULL);
ReleaseInterface(m_pIViewObject2);
}
ReleaseInterface(m_pIOleObject);
ReleaseInterface(m_pObj);
m_pIStorage=NULL; //We'll have already released this.
m_cRef--; //Match safety increment above.
}
//End CHAPTER14MOD
m_fInitialized=TRUE;
//Open the storage for this tenant.
if (!Open(pIStorage))
return FALSE;
hr=OleLoad(m_pIStorage, IID_IUnknown, NULL, (PPVOID)&pObj);
if (FAILED(hr))
{
Destroy(pIStorage);
return FALSE;
}
//CHAPTER17MOD
m_fSetExtent=pti->fSetExtent;
ObjectInitialize(pObj, &pti->fe, NULL);
//Restore the original state before reloading.
m_dwState=dwState;
//End CHAPTER17MOD
RectSet(&pti->rcl, FALSE, FALSE);
return TRUE;
}
/*
* CTenant::GetInfo
*
* Purpose:
* Retrieved a TENANTINFO structure for this tenant.
*
* Parameters:
* pti PTENANTINFO structure to fill
*
* Return Value:
* None
*/
void CTenant::GetInfo(PTENANTINFO pti)
{
if (NULL!=pti)
{
pti->dwID=m_dwID;
pti->rcl=m_rcl;
pti->fe=m_fe;
pti->fSetExtent=m_fSetExtent;
}
return;
}
//CHAPTER17MOD
/*
* CTenant::ObjectInitialize
* (Protected)
*
* Purpose:
* Performs operations necessary after creating an object or
* reloading one from storage.
*
* Parameters:
* pObj LPUNKNOWN of the object in this tenant.
* pFE LPFORMATETC describing the graphic here.
* dwData DWORD extra data. If pFE->dwAspect==
* DVASPECT_ICON then this is the iconic metafile.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*/
BOOL CTenant::ObjectInitialize(LPUNKNOWN pObj, LPFORMATETC pFE
, DWORD dwData)
{
HRESULT hr;
LPPERSIST pIPersist=NULL;
DWORD dw;
PCDocument pDoc;
TCHAR szFile[CCHPATHMAX];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -