home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap24 / patron / iuilink.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  13KB  |  534 lines

  1. /*
  2.  * IUILINK.CPP
  3.  * Patron Chapter 24
  4.  *
  5.  * Implementation of an object with the IOleUILinkContainer
  6.  * interface necessary to use the standard Links Dialog.  This
  7.  * is implemented as a stand-along object with access to the CPage
  8.  * with which its associated, primiarily because it is only used
  9.  * for the one dialog.  Therefore this object has it's own IUnknown.
  10.  * In addition, we use the Links Assistant object developed in this
  11.  * chapter to simplify our own code.
  12.  *
  13.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  14.  *
  15.  * Kraig Brockschmidt, Microsoft
  16.  * Internet  :  kraigb@microsoft.com
  17.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  18.  */
  19.  
  20.  
  21. #include "patron.h"
  22.  
  23.  
  24. /*
  25.  * CIOleUILinkContainer::CIOleUILinkContainer
  26.  * CIOleUILinkContainer::~CIOleUILinkContainer
  27.  *
  28.  * Parameters (Constructor):
  29.  *  pPage           PCPage of the page we're in.
  30.  */
  31.  
  32. CIOleUILinkContainer::CIOleUILinkContainer(PCPage pPage)
  33.     {
  34.     m_cRef=0;
  35.     m_pPage=pPage;
  36.     m_iTenant=0;
  37.     m_pDelIUILinks=NULL;
  38.     m_fDirty=FALSE;
  39.     return;
  40.     }
  41.  
  42. CIOleUILinkContainer::~CIOleUILinkContainer(void)
  43.     {
  44.     ReleaseInterface(m_pDelIUILinks);
  45.     return;
  46.     }
  47.  
  48.  
  49.  
  50. /*
  51.  * CIOleUILinkContainer::Init
  52.  *
  53.  * Purpose:
  54.  *  Performs initialization on the object that might fail.  In
  55.  *  particular this creates an object of CLSID_LinksAssistant that
  56.  *  helps in implementing this interface.
  57.  *
  58.  * Parameters:
  59.  *  None
  60.  *
  61.  * Return Value:
  62.  *  BOOL            TRUE if successful, FALSE otherwise.
  63.  */
  64.  
  65. BOOL CIOleUILinkContainer::Init(void)
  66.     {
  67.     HRESULT     hr;
  68.  
  69.     hr=CoCreateInstance(CLSID_LinksAssistant, NULL
  70.         , CLSCTX_INPROC_SERVER, IID_IOleUILinkContainer
  71.         , (PPVOID)&m_pDelIUILinks);
  72.  
  73.     return SUCCEEDED(hr);
  74.     }
  75.  
  76.  
  77.  
  78.  
  79.  
  80. /*
  81.  * CIOleUILinkContainer::QueryInterface
  82.  * CIOleUILinkContainer::AddRef
  83.  * CIOleUILinkContainer::Release
  84.  *
  85.  * Purpose:
  86.  *  IUnknown members for CIOleUILinkContainer object.
  87.  */
  88.  
  89. STDMETHODIMP CIOleUILinkContainer::QueryInterface(REFIID riid
  90.     , PPVOID ppv)
  91.     {
  92.     *ppv=NULL;
  93.  
  94.     if (IID_IUnknown==riid || IID_IOleUILinkContainer==riid)
  95.         {
  96.         *ppv=this;
  97.         AddRef();
  98.         return NOERROR;
  99.         }
  100.  
  101.     return ResultFromScode(E_NOINTERFACE);
  102.     }
  103.  
  104.  
  105. STDMETHODIMP_(ULONG) CIOleUILinkContainer::AddRef(void)
  106.     {
  107.     return ++m_cRef;
  108.     }
  109.  
  110. STDMETHODIMP_(ULONG) CIOleUILinkContainer::Release(void)
  111.     {
  112.     if (0!=--m_cRef)
  113.         return m_cRef;
  114.  
  115.     delete this;
  116.     return 0;
  117.     }
  118.  
  119.  
  120.  
  121. /*
  122.  * CIOleUILinkContainer::GetNextLink
  123.  *
  124.  * Purpose:
  125.  *  Called when the Links dialog is filling its listbox.  Here we
  126.  *  need to return a key for the first link if dwLink is zero, then
  127.  *  return the next links if it's non-zero.
  128.  *
  129.  * Parameters:
  130.  *  dwLink          DWORD last returned from this function.  Zero if
  131.  *                  this is the first call to this function.
  132.  *
  133.  * Return Value:
  134.  *  DWORD           Some value that identifies this object.  Zero
  135.  *                  stops the sequence such that this function is
  136.  *                  no longer called.
  137.  */
  138.  
  139. STDMETHODIMP_(DWORD) CIOleUILinkContainer::GetNextLink(DWORD dwLink)
  140.     {
  141.     PCTenant        pTenant;
  142.  
  143.     //If we're told to start the sequence, set index to zero.
  144.     if (0L==dwLink)
  145.         m_iTenant=0;
  146.  
  147.     /*
  148.      * On each subsequent call, find the next linked object in
  149.      * this document and return it.  Make sure the index is
  150.      * incremented for the next time this function is called.
  151.      */
  152.     for ( ; m_iTenant < m_pPage->m_cTenants; m_iTenant++)
  153.         {
  154.         if (m_pPage->TenantGet(m_iTenant, &pTenant, FALSE))
  155.             {
  156.             if (TENANTTYPE_LINKEDOBJECT==pTenant->TypeGet())
  157.                 {
  158.                 m_iTenant++;
  159.                 return (DWORD)pTenant;
  160.                 }
  161.             }
  162.         }
  163.  
  164.     //If we hit the end of list, this tells the dialog to stop.
  165.     return 0L;
  166.     }
  167.  
  168.  
  169.  
  170.  
  171.  
  172. /*
  173.  * CIOleUILinkContainer::SetLinkUpdateOptions
  174.  *
  175.  * Purpose:
  176.  *  Informs the application to call IOleLink::SetUpdateOptions for
  177.  *  the object identified by dwLink.
  178.  *
  179.  * Parameters:
  180.  *  dwLink          DWORD object identifier as returned from
  181.  *                  GetNextLink.
  182.  *  dwOptions       DWORD containing the new options.
  183.  *
  184.  * Return Value:
  185.  *  HRESULT         Return value of IOleLink::SetUpdateOptions.
  186.  */
  187.  
  188. STDMETHODIMP CIOleUILinkContainer::SetLinkUpdateOptions(DWORD dwLink
  189.     , DWORD dwOptions)
  190.     {
  191.     LPOLELINK       pIOleLink;
  192.     HRESULT         hr;
  193.  
  194.     if (NULL==dwLink)
  195.         return ResultFromScode(E_FAIL);
  196.  
  197.     /*
  198.      * Your responsibility is to call the object's
  199.      * IOleLink::SetUpdateOptions function with dwOptions.  Simple?
  200.      *
  201.      * For Patron we must first get the object pointer obtainable
  202.      * from the tenant's ObjectGet function, then QI for IOleLink.
  203.      */
  204.  
  205.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  206.  
  207.     if (FAILED(hr))
  208.         return hr;
  209.  
  210.     hr=pIOleLink->SetUpdateOptions(dwOptions);
  211.     pIOleLink->Release();
  212.  
  213.     m_fDirty=SUCCEEDED(hr);
  214.     return hr;
  215.     }
  216.  
  217.  
  218.  
  219.  
  220.  
  221. /*
  222.  * CIOleUILinkContainer::GetLinkUpdateOptions
  223.  *
  224.  * Purpose:
  225.  *  Requests the container to call IOleLink::GetUpdateOptions for
  226.  *  the object identified by dwLink.
  227.  *
  228.  * Parameters:
  229.  *  dwLink          DWORD identifying the object
  230.  *  pdwOptions      LPDWORD in which to store the options.
  231.  *
  232.  * Return Value:
  233.  *  HRESULT         Return value of IOleLink::GetUpdateOptions
  234.  */
  235.  
  236. STDMETHODIMP CIOleUILinkContainer::GetLinkUpdateOptions(DWORD dwLink
  237.     , LPDWORD pdwOptions)
  238.     {
  239.     LPOLELINK       pIOleLink;
  240.     HRESULT         hr;
  241.  
  242.     if (NULL==dwLink)
  243.         return ResultFromScode(E_FAIL);
  244.  
  245.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  246.  
  247.     if (FAILED(hr))
  248.         return hr;
  249.  
  250.     hr=pIOleLink->GetUpdateOptions(pdwOptions);
  251.     pIOleLink->Release();
  252.  
  253.     return hr;
  254.     }
  255.  
  256.  
  257.  
  258.  
  259.  
  260. /*
  261.  * CIOleUILinkContainer::SetLinkSource
  262.  *
  263.  * Purpose:
  264.  *  Changes the moniker to which an object is linked.
  265.  *
  266.  * Parameters:
  267.  *  dwLink          DWORD identifying the object in question.
  268.  *  pszName         LPTSTR to the displayable name of the source.
  269.  *  cchName         ULONG length of the file portaion of pszName
  270.  *  pchEaten        ULONG * in which to return the number of
  271.  *                  characters used in parsing pszDisplayName.
  272.  *  fValidate       BOOL indicating if we're to validate that the
  273.  *                  source exists first.
  274.  *
  275.  * Return Value:
  276.  *  HRESULT         NOERROR if successful, E_FAIL otherwise.
  277.  */
  278.  
  279. STDMETHODIMP CIOleUILinkContainer::SetLinkSource(DWORD dwLink
  280.     , LPTSTR pszName, ULONG cchName, ULONG *pchEaten
  281.     , BOOL fValidate)
  282.     {
  283.     PCTenant        pTenant=(PCTenant)dwLink;
  284.     HRESULT         hr;
  285.     LPOLELINK       pIOleLink;
  286.  
  287.     if (NULL==dwLink)
  288.         return ResultFromScode(E_FAIL);
  289.  
  290.     //This is for use in GetLinkSource, below.
  291.     pTenant->m_fLinkAvail=FALSE;
  292.  
  293.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  294.  
  295.     if (FAILED(hr))
  296.         return hr;
  297.  
  298.     hr=m_pDelIUILinks->SetLinkSource((DWORD)pIOleLink, pszName
  299.         , cchName, pchEaten, fValidate);
  300.     pIOleLink->Release();
  301.  
  302.     if (FAILED(hr))
  303.         return hr;
  304.  
  305.     //hr will be S_FALSE if link is unavailable.
  306.     pTenant->Repaint();
  307.     pTenant->m_fLinkAvail=(NOERROR==hr);
  308.     m_fDirty=TRUE;
  309.     return NOERROR;
  310.     }
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317. /*
  318.  * CIOleUILinkContainer::GetLinkSource
  319.  *
  320.  * Purpose:
  321.  *  Retrieves various strings and values for this link source.
  322.  *
  323.  * Parameters:
  324.  *  dwLink          DWORD identifying the object affected.
  325.  *  ppszName        LPTSTR * in which to return the new source
  326.  *                  name
  327.  *  pcchName        ULONG * in which to return the length of
  328.  *                  pszName
  329.  *  ppszFullLink    LPTSTR * in which to return the full name of
  330.  *                  the class of linked object.
  331.  *  ppszShortLink   LPTSTR * in which to return the short name of
  332.  *                  the class of linked object.
  333.  *  pfSourceAvail   BOOL * in which to return if this is an
  334.  *                  available link source.
  335.  *  pfSelected      BOOL * in which to return if this object is
  336.  *                  currently selected in the document.  This
  337.  *                  selects the item in the listbox for this object.
  338.  *
  339.  * Return Value:
  340.  *  HRESULT         NOERROR on success, error code otherwise.
  341.  */
  342.  
  343. STDMETHODIMP CIOleUILinkContainer::GetLinkSource(DWORD dwLink
  344.     , LPTSTR *ppszName, ULONG *pcchName, LPTSTR *ppszFullLink
  345.     , LPTSTR *ppszShortLink, BOOL *pfSourceAvail, BOOL *pfSelected)
  346.     {
  347.     HRESULT         hr;
  348.     PCTenant        pTenant=(PCTenant)dwLink;
  349.     LPOLELINK       pIOleLink=NULL;
  350.     LPOLEOBJECT     pIOleObject=NULL;
  351.     LPMONIKER       pmk=NULL;
  352.     LPMONIKER       pmkFirst=NULL;
  353.     LPBC            pbc=NULL;
  354.  
  355.     if (NULL==dwLink)
  356.         return ResultFromScode(E_FAIL);
  357.  
  358.     //We know what this is from SetLinkSource
  359.     *pfSourceAvail=pTenant->m_fLinkAvail;
  360.  
  361.     if (pfSelected)
  362.         *pfSelected=pTenant->FIsSelected();
  363.  
  364.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  365.  
  366.     if (FAILED(hr))
  367.         return hr;
  368.  
  369.     hr=m_pDelIUILinks->GetLinkSource((DWORD)pIOleLink, ppszName
  370.         , pcchName, ppszFullLink, ppszShortLink, pfSourceAvail
  371.         , pfSelected);
  372.  
  373.     pIOleLink->Release();
  374.     return hr;
  375.     }
  376.  
  377.  
  378.  
  379.  
  380.  
  381. /*
  382.  * CIOleUILinkContainer::OpenLinkSource
  383.  *
  384.  * Purpose:
  385.  *  Asks the container to call DoVerb on this object with
  386.  *  OLEIVERB_SHOW.
  387.  *
  388.  * Parameters:
  389.  *  dwLink          DWORD identifying the linked object.
  390.  *
  391.  * Return Value:
  392.  *  HRESULT         Standard.
  393.  */
  394.  
  395. STDMETHODIMP CIOleUILinkContainer::OpenLinkSource(DWORD dwLink)
  396.     {
  397.     PCTenant        pTenant=(PCTenant)dwLink;
  398.  
  399.     pTenant->Activate(OLEIVERB_OPEN, NULL);
  400.     return NOERROR;
  401.     }
  402.  
  403.  
  404.  
  405.  
  406. /*
  407.  * CIOleUILinkContainer::UpdateLink
  408.  *
  409.  * Purpose:
  410.  *  Asks the container to update the link for this object.
  411.  *
  412.  * Parameters:
  413.  *  dwLink          DWORD identifying the linked object.
  414.  *  fErrorMessage   BOOL indicating if we can show errors.
  415.  *  fErrorAction    BOOL making no sense whatsoever.
  416.  *
  417.  * Return Value:
  418.  *  HRESULT         Standard.
  419.  */
  420.  
  421. STDMETHODIMP CIOleUILinkContainer::UpdateLink(DWORD dwLink
  422.     , BOOL fErrorMessage, BOOL fErrorAction)
  423.     {
  424.     PCTenant        pTenant=(PCTenant)dwLink;
  425.     LPOLELINK       pIOleLink;
  426.     HRESULT         hr;
  427.  
  428.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  429.  
  430.     if (FAILED(hr))
  431.         return hr;
  432.  
  433.     hr=m_pDelIUILinks->UpdateLink((DWORD)pIOleLink, fErrorMessage
  434.         , fErrorAction);
  435.  
  436.     pTenant->Repaint();
  437.     pTenant->m_fLinkAvail=SUCCEEDED(hr);
  438.     pIOleLink->Release();
  439.  
  440.     if (FAILED(hr))
  441.         {
  442.         if (fErrorMessage)
  443.             {
  444.             MessageBox(m_pPage->m_hWnd
  445.                 , TEXT("Could not update link."), TEXT("Patron")
  446.                 , MB_OK);
  447.             }
  448.         }
  449.     else
  450.         m_fDirty=TRUE;
  451.  
  452.     return hr;
  453.     }
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460. /*
  461.  * CIOleUILinkContainer::CancelLink
  462.  *
  463.  * Purpose:
  464.  *  Requests that the container turn this linked object into a
  465.  *  static object.
  466.  *
  467.  * Parameters:
  468.  *  dwLink          DWORD identifying the linked object.
  469.  *
  470.  * Return Value:
  471.  *  HRESULT         Standard.
  472.  */
  473.  
  474. STDMETHODIMP CIOleUILinkContainer::CancelLink(DWORD dwLink)
  475.     {
  476.     PCTenant        pTenant=(PCTenant)dwLink;
  477.     LPOLELINK       pIOleLink;
  478.     HRESULT         hr;
  479.  
  480.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  481.  
  482.     if (FAILED(hr))
  483.         return hr;
  484.  
  485.     //This sets the source moniker to NULL.
  486.     m_pDelIUILinks->CancelLink((DWORD)pIOleLink);
  487.     pIOleLink->Release();
  488.  
  489.     //Go change this object over to a static one.
  490.     pTenant->ConvertToStatic();
  491.  
  492.     m_fDirty=TRUE;
  493.     return NOERROR;
  494.     }
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501. //PROTECTED FUNCTIONS INTERNAL TO CIOleUILinkContainer
  502.  
  503.  
  504. /*
  505.  * CIOleUILinkContainer::GetObjectInterface
  506.  * (Protected)
  507.  *
  508.  * Purpose:
  509.  *  Retrieves and interface pointer for the object identified by
  510.  *  dwLink
  511.  *
  512.  * Parameters:
  513.  *  dwLink          DWORD identifying the object
  514.  *  riid            REFIID of the interface desired.
  515.  *  ppv             PPVOID into which we return the pointer.
  516.  *
  517.  * Return Value:
  518.  *  HRESULT         NOERROR on success, error code otherwise.
  519.  */
  520.  
  521. STDMETHODIMP CIOleUILinkContainer::GetObjectInterface(DWORD dwLink
  522.     , REFIID riid, PPVOID ppv)
  523.     {
  524.     PCTenant        pTenant=(PCTenant)dwLink;
  525.     LPUNKNOWN       pIUnknown;
  526.     HRESULT         hr;
  527.  
  528.     pTenant->ObjectGet(&pIUnknown);
  529.     hr=pIUnknown->QueryInterface(riid, ppv);
  530.     pIUnknown->Release();
  531.  
  532.     return hr;
  533.     }
  534.