⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tenant.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 * TENANT.CPP
 * Patron Chapter 24
 *
 * 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;

    m_cRef=0;
    m_pIOleObject=NULL;
    m_pIViewObject2=NULL;
    m_grfMisc=0;

    m_pImpIOleClientSite=NULL;
    m_pImpIAdviseSink=NULL;

    m_fRepaintEnabled=TRUE;
    m_pmkFile=NULL;
    m_fLinkAvail=TRUE;          //Checked on Load
    m_pmk=NULL;

    m_pImpIOleIPSite=NULL;
    m_pIOleIPObject=NULL;
    m_rcPos.left=-1;
    m_fInRectSet=FALSE;

    //CHAPTER24MOD
    m_pImpIOleControlSite=NULL;
    m_pImpIDispatch=NULL;

    m_pDispEvents=NULL;
    m_dwConnEvents=0L;
    m_iidEvents=GUID_NULL;
    m_pEventMap=NULL;

    m_pIOleControl=NULL;
    m_pIDispatchControl=NULL;

    //0x80000000 in OLE_COLOR indicates low byte is color index.
    m_clrBack=0x80000000+COLOR_WINDOW;
    m_clrFore=0x80000000+COLOR_WINDOWTEXT;

    m_pIFont=m_pPG->m_pIFont;
    m_lcid=LOCALE_USER_DEFAULT;
    m_fDesignMode=m_pPG->m_fDesignMode;
    m_fUIDead=m_pPG->m_fUIDead;
    m_fHatchHandles=m_pPG->m_fHatchHandles;

    m_fHaveControlInfo=FALSE;
    m_cLockInPlace=0;
    m_fPendingDeactivate=FALSE;
    //End CHAPTER24MOD

    return;
    }


CTenant::~CTenant(void)
    {
    ReleaseInterface(m_pmk);
    ReleaseInterface(m_pmkFile);

    //Object pointers cleaned up in Close.

    //CHAPTER24MOD
    if (NULL!=m_pEventMap)
        delete m_pEventMap;

    DeleteInterfaceImp(m_pImpIOleControlSite);
    DeleteInterfaceImp(m_pImpIDispatch);

    if (NULL!=m_pDispEvents)
        delete m_pDispEvents;
    //End CHAPTER24MOD

    DeleteInterfaceImp(m_pImpIOleIPSite);
    DeleteInterfaceImp(m_pImpIAdviseSink);
    DeleteInterfaceImp(m_pImpIOleClientSite);
    return;
    }




/*
 * 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 (IID_IOleWindow==riid || IID_IOleInPlaceSite==riid)
        *ppv=m_pImpIOleIPSite;

    //CHAPTER24MOD
    if (IID_IOleControlSite==riid)
        *ppv=m_pImpIOleControlSite;

    //Queries for IDispatch return the ambient properties interface
    if (IID_IDispatch==riid)
        *ppv=m_pImpIDispatch;
    //End CHAPTER24MOD

    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;
    }






/*
 * 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
    }



/*
 * 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;
    }




/*
 * 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;

    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;

        case TENANTTYPE_EMBEDDEDOBJECT:
            //CHAPTER24MOD
            /*
             * The OLE Control specifications mention that a
             * a control might implement IPersistStream[Init]
             * instead of IPersistStorage.  In that case you
             * cannot use OleCreate on a control but must rather
             * use CoCreateInstance since OleCreate assumes
             * that IPersistStorage is available.  With a control,
             * you would have to create the object first, then
             * check if OLEMISC_SETCLIENTSITEFIRST is set, then
             * send it your IOleClientSite first.  Then you check
             * for IPersistStorage and failing that, try
             * IPersistStream[Init].
             *
             * For simplicity we'll assume storage-based
             * controls in this sample.
             */
            //End CHAPTER24MOD

            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;

        case TENANTTYPE_LINKEDFILE:
            hr=OleCreateLinkToFile((LPTSTR)pvType, IID_IUnknown
                , OLERENDER_DRAW, NULL, NULL, m_pIStorage
                , (PPVOID)&pObj);
            break;

        case TENANTTYPE_LINKEDOBJECTFROMDATA:
            hr=OleCreateLinkFromData((LPDATAOBJECT)pvType
                , IID_IUnknown, OLERENDER_DRAW, NULL, NULL
                , m_pIStorage, (PPVOID)&pObj);
            break;

        default:
            break;
        }

    //If creation didn't work, get rid of the element Open created.
    if (FAILED(hr))
        {
        Destroy(pIStorage);
        return CREATE_FAILED;
        }

    //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);
            }
        }

    //CHAPTER24MOD
    //Make sure this happens
    if ((OLEMISC_ACTIVATEWHENVISIBLE & m_grfMisc) && !m_fDesignMode)
        Activate(OLEIVERB_INPLACEACTIVATE, NULL);
    //End CHAPTER24MOD

    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;
    DWORD           dwState=TENANTSTATE_DEFAULT;

    if (NULL==pIStorage || NULL==pti)
        return FALSE;

    /*
     * 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.
        }

    m_fInitialized=TRUE;

    //Open the storage for this tenant.
    if (!Open(pIStorage))
        return FALSE;

    /*
     * NOTE:  If you do not pass an IOleClientSite to OleLoad
     * it will not automatically reconnect a linked object to

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -