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

📄 fileobj.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * FILEOBJ.CPP
 * File Object for Link Source, Chapter 9
 *
 * Implementation of a "file" object named with a file moniker,
 * which implements IPersistFile, IOleItemContainer, and
 * IDescription.  The latter two interfaces are implemented
 * generically in IOLECONT.CPP and IDESCRIP.CPP.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "linksrc.h"

#ifdef WIN32ANSI
/*
 * This is to turn off the mapping to ANSI wrapper APIs because
 * we're actually using wide char strings under Win32 all the time
 * in parts of this code.
 */
#undef StgOpenStorage
#define StgOpenStorage StgOpenStorage

#undef CreateFileMoniker
#define CreateFileMoniker CreateFileMoniker
#endif


/*
 * CFileObject::CFileObject
 * CFileObject::~CFileObject
 *
 * Parameters (Constructor):
 *  pUnkOuter       LPUNKNOWN of a controlling unknown.
 *  pfnDestroy      PFNDESTROYED to call when an object
 *                  is destroyed.
 */

CFileObject::CFileObject(LPUNKNOWN pUnkOuter
    , PFNDESTROYED pfnDestroy)
    {
    m_cRef=0;
    m_pUnkOuter=pUnkOuter;
    m_pfnDestroy=pfnDestroy;

    m_clsID=CLSID_LinkedFile;
    m_szFile[0]=(OLECHAR)0;
    m_pIStorage=NULL;
    m_pmk=NULL;
    m_dwRegROT=0;

    m_pImpIPersistFile=NULL;
    m_pImpIOleItemContainer=NULL;
    m_pImpIDescription=NULL;

    return;
    }

CFileObject::~CFileObject(void)
    {
    //Remove us from the running object table
    if (0!=m_dwRegROT)
        {
        IRunningObjectTable    *pROT;

        if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
            {
            pROT->Revoke(m_dwRegROT);
            pROT->Release();
            }
        }

    ReleaseInterface(m_pmk);
    ReleaseInterface(m_pIStorage);
    DeleteInterfaceImp(m_pImpIDescription);
    DeleteInterfaceImp(m_pImpIOleItemContainer);
    DeleteInterfaceImp(m_pImpIPersistFile);
    return;
    }



/*
 * CFileObject::Init
 *
 * Purpose:
 *  Performs any intiailization of a CFileObject 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 CFileObject::Init(void)
    {
    IUnknown   *pUnk=this;

    if (NULL!=m_pUnkOuter)
        pUnk=m_pUnkOuter;

    m_pImpIPersistFile=new CImpIPersistFile(this, pUnk);

    if (NULL==m_pImpIPersistFile)
        return FALSE;

    m_pImpIOleItemContainer=new CImpIOleItemContainer(this, pUnk
        , TRUE);

    if (NULL==m_pImpIOleItemContainer)
        return FALSE;

    m_pImpIDescription=new CImpIDescription(pUnk);

    if (NULL==m_pImpIDescription)
        return FALSE;

    return TRUE;
    }




/*
 * CFileObject::QueryInterface
 * CFileObject::AddRef
 * CFileObject::Release
 *
 * Purpose:
 *  IUnknown members for CFileObject object.
 */

STDMETHODIMP CFileObject::QueryInterface(REFIID riid, PPVOID ppv)
    {
    *ppv=NULL;

    if (IID_IUnknown==riid)
        *ppv=this;

    if (IID_IPersist==riid || IID_IPersistFile==riid)
        *ppv=m_pImpIPersistFile;

    if (IID_IParseDisplayName==riid || IID_IOleContainer==riid
        || IID_IOleItemContainer==riid)
        *ppv=m_pImpIOleItemContainer;

    if (IID_IDescription==riid)
        *ppv=m_pImpIDescription;

    if (NULL!=*ppv)
        {
        ((LPUNKNOWN)*ppv)->AddRef();
        return NOERROR;
        }

    return ResultFromScode(E_NOINTERFACE);
    }


STDMETHODIMP_(ULONG) CFileObject::AddRef(void)
    {
    return ++m_cRef;
    }


STDMETHODIMP_(ULONG) CFileObject::Release(void)
    {
    if (0L!=--m_cRef)
        return m_cRef;

    if (NULL!=m_pfnDestroy)
        (*m_pfnDestroy)();

    delete this;
    return 0;
    }




/**
 ** IPersistFile implementation
 **/

/*
 * CImpIPersistFile:CImpIPersistFile
 * CImpIPersistFile::~CImpIPersistFile
 * CImpIPersistFile::QueryInterface
 * CImpIPersistFile::AddRef
 * CImpIPersistFile::Release
 *
 * Basic object members.
 */

CImpIPersistFile::CImpIPersistFile(PCFileObject pObj
    , LPUNKNOWN pUnkOuter)
    {
    m_cRef=0;
    m_pObj=pObj;
    m_pUnkOuter=pUnkOuter;
    return;
    }

CImpIPersistFile::~CImpIPersistFile(void)
    {
    return;
    }

STDMETHODIMP CImpIPersistFile::QueryInterface(REFIID riid
    , LPVOID *ppv)
    {
    return m_pUnkOuter->QueryInterface(riid, ppv);
    }

STDMETHODIMP_(ULONG) CImpIPersistFile::AddRef(void)
    {
    ++m_cRef;
    return m_pUnkOuter->AddRef();
    }

STDMETHODIMP_(ULONG) CImpIPersistFile::Release(void)
    {
    --m_cRef;
    return m_pUnkOuter->Release();
    }





/*
 * CImpIPersistFile::GetClassID
 * CImpIPersistFile::IsDirty
 * CImpIPersistFile::Save
 * CImpIPersistFile::SaveCompleted
 *
 * Trivial or unimplemented members.
 */

STDMETHODIMP CImpIPersistFile::GetClassID(LPCLSID pClsID)
    {
    *pClsID=m_pObj->m_clsID;
    return NOERROR;
    }

STDMETHODIMP CImpIPersistFile::IsDirty(void)
    {
    //We're never dirty
    return ResultFromScode(S_FALSE);
    }

STDMETHODIMP CImpIPersistFile::Save(LPCOLESTR pszFile, BOOL fRemember)
    {
    return ResultFromScode(E_NOTIMPL);
    }

STDMETHODIMP CImpIPersistFile::SaveCompleted(LPCOLESTR pszFile)
    {
    return NOERROR;
    }





/*
 * CImpIPersistFile::Load
 *
 * Purpose:
 *  Asks the server to load the document for the given filename.
 *
 * Parameters:
 *  pszFile         LPCOLESTR of the filename to load.
 *  grfMode         DWORD flags to use when opening the file.
 */

STDMETHODIMP CImpIPersistFile::Load(LPCOLESTR pszFile, DWORD grfMode)
    {
    const int   cch=512;
    HRESULT     hr;

    //We should only be loaded once; having a moniker tells us
    if (NULL!=m_pObj->m_pmk)
        return ResultFromScode(E_UNEXPECTED);

    /*
     * Since the server is single-use, we can be assured that
     * this Load will only happen once, so we can hold the
     * IStorage until the object is released.
     */
    hr=StgOpenStorage(pszFile, NULL
        , STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0
        , &m_pObj->m_pIStorage);

    if (FAILED(hr))
        return hr;

    m_pObj->m_pImpIDescription->SetStorage(m_pObj->m_pIStorage);

    /*
     * We opened it successfully, and that's all we have to
     * do, so we can simply save the filename.
     */
   #ifdef WIN32ANSI
    wcsncpy(m_pObj->m_szFile, pszFile, cch);
   #else
    lstrcpyn(m_pObj->m_szFile, pszFile, cch);
   #endif

    /*
     * Create a moniker for this file object and register as
     * running.
     */
    if (SUCCEEDED(CreateFileMoniker(pszFile, &m_pObj->m_pmk)))
        {
        IRunningObjectTable    *pROT;

        if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
            {
            //Register as weak so clients can free us
            pROT->Register(0, m_pObj, m_pObj->m_pmk
                , &m_pObj->m_dwRegROT);
            pROT->Release();
            }
        }

    return NOERROR;
    }



/*
 * CImpIPersistFile::GetCurFile
 *
 * Purpose:
 *  Returns the current filename.
 *
 * Parameters:
 *  ppszFile        LPOLESTR * into which we store a pointer to
 *                  the filename that should be allocated with the
 *                  shared IMalloc.
 */

STDMETHODIMP CImpIPersistFile::GetCurFile(LPOLESTR *ppszFile)
    {
    LPMALLOC    pIMalloc;
    const int   cch=512;
    LPOLESTR    psz;

    *ppszFile=NULL;

    if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
        return ResultFromScode(E_FAIL);

    psz=(LPOLESTR)pIMalloc->Alloc(cch*sizeof(OLECHAR));
    pIMalloc->Release();

    if (NULL==psz)
        return ResultFromScode(E_OUTOFMEMORY);

   #ifdef WIN32ANSI
    wcsncpy(psz, m_pObj->m_szFile, cch);
   #else
    lstrcpyn(psz, m_pObj->m_szFile, cch);
   #endif
    *ppszFile=psz;
    return NOERROR;
    }

⌨️ 快捷键说明

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