SITE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * SITE.CPP
  3.  * Document Object Site Object
  4.  *
  5.  * Copyright (c)1995-1997 Microsoft Corporation, All Rights Reserved
  6.  */
  7. #include "framer.h"
  8. /*
  9.  * CSite::CSite
  10.  * CSite::~CSite
  11.  *
  12.  * Constructor Parameters:
  13.  *  dwID            DWORD identifer for this site.
  14.  *  hWnd            HWND of the window associated with the site
  15.  *  pFR             PCFrame to the parent structure.
  16.  */
  17. CSite::CSite(DWORD dwID, HWND hWnd, PCFrame pFR)
  18.     {
  19.     m_cRef=0;
  20.     m_dwID=dwID;
  21.     m_hWnd=hWnd;
  22.     m_pFR=pFR;
  23.     m_fInitialized=0;
  24.     m_pIStorage=NULL;
  25.     m_pObj=NULL;
  26.     
  27.     m_pIOleObject=NULL;
  28.     m_pIOleIPObject=NULL;
  29.     m_pIOleDocView=NULL;
  30.     m_pImpIOleClientSite=NULL;
  31.     m_pImpIAdviseSink=NULL;
  32.     m_pImpIOleIPSite=NULL;
  33.     m_pImpIOleDocumentSite=NULL;
  34.     m_fDocObj=FALSE;
  35.     return;
  36.     }
  37. CSite::~CSite(void)
  38.     {
  39.     //Object pointers cleaned up in Close.
  40.     //We delete our own interfaces since we control them
  41.     DeleteInterfaceImp(m_pImpIOleDocumentSite);
  42.     DeleteInterfaceImp(m_pImpIOleIPSite);
  43.     DeleteInterfaceImp(m_pImpIAdviseSink);
  44.     DeleteInterfaceImp(m_pImpIOleClientSite);
  45.     return;
  46.     }
  47. /*
  48.  * CSite::QueryInterface
  49.  * CSite::AddRef
  50.  * CSite::Release
  51.  *
  52.  * Purpose:
  53.  *  IUnknown members for CSite object.
  54.  */
  55. STDMETHODIMP CSite::QueryInterface(REFIID riid, void **ppv)
  56.     {
  57.     *ppv=NULL;
  58.     if (IID_IUnknown==riid)
  59.         *ppv=this;
  60.     if (IID_IOleClientSite==riid)
  61.         *ppv=m_pImpIOleClientSite;
  62.     if (IID_IAdviseSink==riid)
  63.         *ppv=m_pImpIAdviseSink;
  64.     if (IID_IOleWindow==riid || IID_IOleInPlaceSite==riid)
  65.         *ppv=m_pImpIOleIPSite;
  66.     if (IID_IOleDocumentSite==riid)
  67.         *ppv=m_pImpIOleDocumentSite;
  68.     if (NULL!=*ppv)
  69.         {
  70.         ((LPUNKNOWN)*ppv)->AddRef();
  71.         return NOERROR;
  72.         }
  73.     return ResultFromScode(E_NOINTERFACE);
  74.     }
  75. STDMETHODIMP_(ULONG) CSite::AddRef(void)
  76.     {
  77.     return ++m_cRef;
  78.     }
  79. STDMETHODIMP_(ULONG) CSite::Release(void)
  80.     {
  81.     if (0!=--m_cRef)
  82.         return m_cRef;
  83.     delete this;
  84.     return 0;
  85.     }
  86. /*
  87.  * CSite::Create
  88.  *
  89.  * Purpose:
  90.  *  Asks the site to instantiate an object given a filename.
  91.  *  This goes through OleCreateFromFile and will either create
  92.  *  an embedded object or a package (embedded) object.  When
  93.  *  activated, this will either launch the app and activate
  94.  *  as a DocObject, launch the app and open the file, or fail
  95.  *  because no app can open the file.
  96.  *
  97.  * Parameters:
  98.  *  pszFile         LPTSTR of the file from which to create the object.
  99.  *  pIStorage       IStorage * of the parent storage in which we're
  100.  *                  to create an IStorage for the new object.
  101.  *  dwID            DWORD identifier for this site.
  102.  *
  103.  * Return Value:
  104.  *  BOOL            Result of the creation.
  105.  */
  106. BOOL CSite::Create(LPTSTR pszFile, IStorage *pIStorage)
  107.     {
  108.     HRESULT             hr=E_FAIL;
  109.     LPUNKNOWN           pObj;
  110.     //Create a new storage for this object (sets m_pIStorage)
  111.     if (!CreateStorage(pIStorage))
  112.         return FALSE;
  113.     //Now create an object from the file
  114.    #ifdef UNICODE    
  115.     hr=OleCreateFromFile(CLSID_NULL, pszFile, IID_IUnknown
  116.         , OLERENDER_NONE, NULL, NULL, m_pIStorage, (void **)&pObj);
  117.    #else
  118.     OLECHAR     szFile[512];    //Assumption on string length
  119.     MultiByteToWideChar(CP_ACP, 0, pszFile, -1, szFile, 512);    
  120. hr=OleCreateFromFile(CLSID_NULL, szFile, IID_IUnknown
  121.         , OLERENDER_NONE, NULL, NULL, m_pIStorage, (void **)&pObj);
  122.    #endif
  123.     //If creation didn't work, get rid of the element Open created.
  124.     if (FAILED(hr))
  125.         {
  126.         Destroy(pIStorage);
  127.         return FALSE;
  128.         }
  129.     //We don't get the size if PatronObject data was seen already.
  130.     if (!ObjectInitialize(pObj))
  131.         {
  132.         Destroy(pIStorage);
  133.         return FALSE;
  134.         }
  135.     m_fInitialized=TRUE;
  136.     return TRUE;
  137.     }
  138. /*
  139.  * CSite::ObjectInitialize
  140.  * (Protected)
  141.  *
  142.  * Purpose:
  143.  *  Performs operations necessary after creating an object or
  144.  *  reloading one from storage.
  145.  *
  146.  * Parameters:
  147.  *  pObj            LPUNKNOWN of the object in this tenant.
  148.  *  pFE             LPFORMATETC describing the graphic here.
  149.  *  dwData          DWORD extra data.  If pFE->dwAspect==
  150.  *                  DVASPECT_ICON then this is the iconic metafile.
  151.  *
  152.  * Return Value:
  153.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  154.  */
  155. BOOL CSite::ObjectInitialize(LPUNKNOWN pObj)
  156.     {
  157.     HRESULT         hr;
  158.     DWORD           dw;
  159.     if (NULL==pObj)
  160.         return FALSE;
  161.     m_pObj=pObj;
  162.     //We need an IOleObject most of the time, so get one here.
  163.     m_pIOleObject=NULL;
  164.     hr=pObj->QueryInterface(IID_IOleObject, (void **)&m_pIOleObject);         
  165.     /*
  166.      * Follow up object creation with advises and so forth.  If
  167.      * we cannot get IOleObject here, then we know we can't do
  168.      * any IOleObject actions from here on--object is static.
  169.      */
  170.     if (FAILED(hr))
  171.         return TRUE;
  172.     //SetClientSite is critical for DocObjects
  173.     m_pIOleObject->SetClientSite(m_pImpIOleClientSite);
  174.     m_pIOleObject->Advise(m_pImpIAdviseSink, &dw);
  175. //This is to give PowerPoint a chance to initialize itself earlier
  176. OleRun(m_pIOleObject);
  177.     return TRUE;
  178.     }
  179. /*
  180.  * CSite::CreateStorage
  181.  *
  182.  * Purpose:
  183.  *  Creates an sub-storage within a given parent storage,
  184.  *  setting m_pIStorage.
  185.  *
  186.  * Parameters:
  187.  *  pIStorage       IStorage * of the parent storage
  188.  *
  189.  * Return Value:
  190.  *  BOOL            TRUE if creation succeeds, FALSE otherwise.
  191.  */
  192. BOOL CSite::CreateStorage(IStorage *pIStorage)
  193.     {
  194.     HRESULT     hr;
  195.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE
  196.                     | STGM_SHARE_EXCLUSIVE;
  197.     TCHAR       szName[32];
  198.     if (NULL==pIStorage)
  199.         return FALSE;
  200.     /*
  201.      * Attempt to open the storage under this ID.  If there is
  202.      * none, then create it.  In either case we end up with an
  203.      * IStorage that we either save in pPage or release.
  204.      */
  205.     wsprintf(szName, TEXT("Site %lu"), m_dwID);
  206.    #ifdef UNICODE
  207.     hr=pIStorage->CreateStorage(szName, dwMode, 0, 0, &m_pIStorage);
  208.    #else
  209.     OLECHAR  szwName[32];
  210. MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, 32);    
  211.     hr=pIStorage->CreateStorage(szwName, dwMode, 0, 0, &m_pIStorage);
  212.    #endif
  213.     if (FAILED(hr))
  214.         return FALSE;
  215. //Create stream for the object; name is irrelevant
  216. dwMode=STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  217.    #ifdef UNICODE
  218.     hr=m_pIStorage->CreateStream(TEXT("03DocObjInfo"), dwMode, 0, 0
  219.         , &m_pIStream);
  220.    #else    
  221. MultiByteToWideChar(CP_ACP, 0, "03DocObjInfo", -1, szwName, 32);    
  222.     hr=m_pIStorage->CreateStream(szwName, dwMode, 0, 0, &m_pIStream);
  223.    #endif
  224.    
  225.     //If we failed to create a stream in the file, do it in memory
  226. if (FAILED(hr))
  227. {
  228. if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &m_pIStream)))
  229.     return FALSE;
  230. }
  231.     //Create interface implementations
  232.     m_pImpIOleClientSite=new CImpIOleClientSite(this, this);
  233.     m_pImpIAdviseSink=new CImpIAdviseSink(this, this);
  234.     m_pImpIOleIPSite=new CImpIOleInPlaceSite(this, this);
  235.     m_pImpIOleDocumentSite=new CImpIOleDocumentSite(this, this);
  236.     if (NULL==m_pImpIOleClientSite || NULL==m_pImpIAdviseSink
  237.         || NULL==m_pImpIOleIPSite || NULL==m_pImpIOleDocumentSite)
  238.         return FALSE;
  239.     return TRUE;
  240.     }
  241. /*
  242.  * CSite::Close
  243.  *
  244.  * Purpose:
  245.  *  Possibly commits the storage, then releases it, afterwards
  246.  *  frees alls the object pointers.
  247.  *
  248.  * Parameters:
  249.  *  fCommit         BOOL indicating if we're to commit.
  250.  *
  251.  * Return Value:
  252.  *  None
  253.  */
  254. void CSite::Close(BOOL fCommit)
  255.     {
  256.     //OnInPlaceDeactivate releases this pointer.
  257.     if (NULL!=m_pIOleIPObject)
  258.         m_pIOleIPObject->InPlaceDeactivate();
  259.     ReleaseInterface(m_pIOleDocView);
  260.     if (NULL!=m_pIOleObject)
  261.         {
  262.         m_pIOleObject->Close(fCommit
  263.             ? OLECLOSE_SAVEIFDIRTY : OLECLOSE_NOSAVE);
  264.         ReleaseInterface(m_pIOleObject);
  265.         }
  266.     ReleaseInterface(m_pObj);
  267. ReleaseInterface(m_pIStream);
  268.     ReleaseInterface(m_pIStorage);
  269.     return;
  270.     }
  271. /*
  272.  * CSite::Update
  273.  *
  274.  * Purpose:
  275.  *  Forces a commit on the object's storage
  276.  *
  277.  * Parameters:
  278.  *  None
  279.  *
  280.  * Return Value:
  281.  *  None
  282.  */
  283. void CSite::Update(void)
  284.     {
  285.     LPPERSISTSTORAGE    pIPS;
  286.     if (NULL!=m_pIStorage)
  287.         return;
  288.     m_pObj->QueryInterface(IID_IPersistStorage, (void **)&pIPS);
  289.     OleSave(pIPS, m_pIStorage, TRUE);
  290.     pIPS->SaveCompleted(NULL);
  291.     pIPS->Release();
  292.     m_pIStorage->Commit(STGC_DEFAULT);
  293.     return;
  294.     }
  295. /*
  296.  * CSite::Destroy
  297.  *
  298.  * Purpose:
  299.  *  Removes this storage from the parent storage.  The caller should
  300.  *  eventually delete this CSite object to free the object herein.
  301.  *  Nothing is committed when being destroyed.
  302.  *
  303.  * Parameters:
  304.  *  pIStorage       IStorage * of the parent
  305.  *
  306.  * Return Value:
  307.  *  None
  308.  */
  309. void CSite::Destroy(IStorage *pIStorage)
  310.     {
  311.     TCHAR     szName[32];
  312.     if (NULL==pIStorage)
  313.         return;
  314.     if (NULL!=m_pObj)
  315.         Close(FALSE);
  316.     
  317. wsprintf(szName, TEXT("Site %lu"), m_dwID);
  318.    #ifdef UNICODE
  319.     pIStorage->DestroyElement(szName);
  320.    #else
  321.     OLECHAR  szwName[32];
  322. MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, 512);    
  323. pIStorage->DestroyElement(szwName);    
  324.    #endif
  325.     return;
  326.     }
  327. /*
  328.  * CSite::Activate
  329.  *
  330.  * Purpose:
  331.  *  Activates a verb on the object living in the site.
  332.  *
  333.  * Parameters:
  334.  *  iVerb           LONG of the verb to execute.
  335.  *
  336.  * Return Value:
  337.  *  None
  338.  */
  339. void CSite::Activate(LONG iVerb)
  340.     {
  341.     CHourglass *pHour;
  342.     RECT        rc;
  343.             
  344.     pHour=new CHourglass;
  345.     GetClientRect(m_hWnd, &rc);
  346.     m_pIOleObject->DoVerb(iVerb, NULL, m_pImpIOleClientSite, 0
  347.         , m_hWnd, &rc);
  348.     delete pHour;
  349.     return;
  350.     }
  351. /*
  352.  * CSite::UpdateObjectRects
  353.  *
  354.  * Purpose:
  355.  *  Informs the site that the client area window was resized and
  356.  *  that the site needs to also tell the DocObject of the resize.
  357.  *
  358.  * Parameters:
  359.  *  None
  360.  *
  361.  * Return Value:
  362.  *  None
  363.  */
  364. void CSite::UpdateObjectRects(void)
  365.     {
  366.     RECT    rc;
  367.     if (NULL==m_pIOleDocView)
  368.         return;
  369.     GetClientRect(m_hWnd, &rc);
  370.     m_pIOleDocView->SetRect(&rc);
  371.     return;
  372.     }