home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / activedocument / framer / site.cpp < prev    next >
C/C++ Source or Header  |  1997-08-12  |  11KB  |  480 lines

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