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

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * IUILINK.CPP
  3.  * Patron Chapter 21
  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. #include "patron.h"
  20. /*
  21.  * CIOleUILinkContainer::CIOleUILinkContainer
  22.  * CIOleUILinkContainer::~CIOleUILinkContainer
  23.  *
  24.  * Parameters (Constructor):
  25.  *  pPage           PCPage of the page we're in.
  26.  */
  27. CIOleUILinkContainer::CIOleUILinkContainer(PCPage pPage)
  28.     {
  29.     m_cRef=0;
  30.     m_pPage=pPage;
  31.     m_iTenant=0;
  32.     m_pDelIUILinks=NULL;
  33.     m_fDirty=FALSE;
  34.     return;
  35.     }
  36. CIOleUILinkContainer::~CIOleUILinkContainer(void)
  37.     {
  38.     ReleaseInterface(m_pDelIUILinks);
  39.     return;
  40.     }
  41. /*
  42.  * CIOleUILinkContainer::Init
  43.  *
  44.  * Purpose:
  45.  *  Performs initialization on the object that might fail.  In
  46.  *  particular this creates an object of CLSID_LinksAssistant that
  47.  *  helps in implementing this interface.
  48.  *
  49.  * Parameters:
  50.  *  None
  51.  *
  52.  * Return Value:
  53.  *  BOOL            TRUE if successful, FALSE otherwise.
  54.  */
  55. BOOL CIOleUILinkContainer::Init(void)
  56.     {
  57.     HRESULT     hr;
  58.     hr=CoCreateInstance(CLSID_LinksAssistant, NULL
  59.         , CLSCTX_INPROC_SERVER, IID_IOleUILinkContainer
  60.         , (PPVOID)&m_pDelIUILinks);
  61.     return SUCCEEDED(hr);
  62.     }
  63. /*
  64.  * CIOleUILinkContainer::QueryInterface
  65.  * CIOleUILinkContainer::AddRef
  66.  * CIOleUILinkContainer::Release
  67.  *
  68.  * Purpose:
  69.  *  IUnknown members for CIOleUILinkContainer object.
  70.  */
  71. STDMETHODIMP CIOleUILinkContainer::QueryInterface(REFIID riid
  72.     , PPVOID ppv)
  73.     {
  74.     *ppv=NULL;
  75.     if (IID_IUnknown==riid || IID_IOleUILinkContainer==riid)
  76.         {
  77.         *ppv=this;
  78.         AddRef();
  79.         return NOERROR;
  80.         }
  81.     return ResultFromScode(E_NOINTERFACE);
  82.     }
  83. STDMETHODIMP_(ULONG) CIOleUILinkContainer::AddRef(void)
  84.     {
  85.     return ++m_cRef;
  86.     }
  87. STDMETHODIMP_(ULONG) CIOleUILinkContainer::Release(void)
  88.     {
  89.     if (0!=--m_cRef)
  90.         return m_cRef;
  91.     delete this;
  92.     return 0;
  93.     }
  94. /*
  95.  * CIOleUILinkContainer::GetNextLink
  96.  *
  97.  * Purpose:
  98.  *  Called when the Links dialog is filling its listbox.  Here we
  99.  *  need to return a key for the first link if dwLink is zero, then
  100.  *  return the next links if it's non-zero.
  101.  *
  102.  * Parameters:
  103.  *  dwLink          DWORD last returned from this function.  Zero if
  104.  *                  this is the first call to this function.
  105.  *
  106.  * Return Value:
  107.  *  DWORD           Some value that identifies this object.  Zero
  108.  *                  stops the sequence such that this function is
  109.  *                  no longer called.
  110.  */
  111. STDMETHODIMP_(DWORD) CIOleUILinkContainer::GetNextLink(DWORD dwLink)
  112.     {
  113.     PCTenant        pTenant;
  114.     //If we're told to start the sequence, set index to zero.
  115.     if (0L==dwLink)
  116.         m_iTenant=0;
  117.     /*
  118.      * On each subsequent call, find the next linked object in
  119.      * this document and return it.  Make sure the index is
  120.      * incremented for the next time this function is called.
  121.      */
  122.     for ( ; m_iTenant < m_pPage->m_cTenants; m_iTenant++)
  123.         {
  124.         if (m_pPage->TenantGet(m_iTenant, &pTenant, FALSE))
  125.             {
  126.             if (TENANTTYPE_LINKEDOBJECT==pTenant->TypeGet())
  127.                 {
  128.                 m_iTenant++;
  129.                 return (DWORD)pTenant;
  130.                 }
  131.             }
  132.         }
  133.     //If we hit the end of list, this tells the dialog to stop.
  134.     return 0L;
  135.     }
  136. /*
  137.  * CIOleUILinkContainer::SetLinkUpdateOptions
  138.  *
  139.  * Purpose:
  140.  *  Informs the application to call IOleLink::SetUpdateOptions for
  141.  *  the object identified by dwLink.
  142.  *
  143.  * Parameters:
  144.  *  dwLink          DWORD object identifier as returned from
  145.  *                  GetNextLink.
  146.  *  dwOptions       DWORD containing the new options.
  147.  *
  148.  * Return Value:
  149.  *  HRESULT         Return value of IOleLink::SetUpdateOptions.
  150.  */
  151. STDMETHODIMP CIOleUILinkContainer::SetLinkUpdateOptions(DWORD dwLink
  152.     , DWORD dwOptions)
  153.     {
  154.     LPOLELINK       pIOleLink;
  155.     HRESULT         hr;
  156.     if (NULL==dwLink)
  157.         return ResultFromScode(E_FAIL);
  158.     /*
  159.      * Your responsibility is to call the object's
  160.      * IOleLink::SetUpdateOptions function with dwOptions.  Simple?
  161.      *
  162.      * For Patron we must first get the object pointer obtainable
  163.      * from the tenant's ObjectGet function, then QI for IOleLink.
  164.      */
  165.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  166.     if (FAILED(hr))
  167.         return hr;
  168.     hr=pIOleLink->SetUpdateOptions(dwOptions);
  169.     pIOleLink->Release();
  170.     m_fDirty=SUCCEEDED(hr);
  171.     return hr;
  172.     }
  173. /*
  174.  * CIOleUILinkContainer::GetLinkUpdateOptions
  175.  *
  176.  * Purpose:
  177.  *  Requests the container to call IOleLink::GetUpdateOptions for
  178.  *  the object identified by dwLink.
  179.  *
  180.  * Parameters:
  181.  *  dwLink          DWORD identifying the object
  182.  *  pdwOptions      LPDWORD in which to store the options.
  183.  *
  184.  * Return Value:
  185.  *  HRESULT         Return value of IOleLink::GetUpdateOptions
  186.  */
  187. STDMETHODIMP CIOleUILinkContainer::GetLinkUpdateOptions(DWORD dwLink
  188.     , LPDWORD pdwOptions)
  189.     {
  190.     LPOLELINK       pIOleLink;
  191.     HRESULT         hr;
  192.     if (NULL==dwLink)
  193.         return ResultFromScode(E_FAIL);
  194.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  195.     if (FAILED(hr))
  196.         return hr;
  197.     hr=pIOleLink->GetUpdateOptions(pdwOptions);
  198.     pIOleLink->Release();
  199.     return hr;
  200.     }
  201. /*
  202.  * CIOleUILinkContainer::SetLinkSource
  203.  *
  204.  * Purpose:
  205.  *  Changes the moniker to which an object is linked.
  206.  *
  207.  * Parameters:
  208.  *  dwLink          DWORD identifying the object in question.
  209.  *  pszName         LPTSTR to the displayable name of the source.
  210.  *  cchName         ULONG length of the file portaion of pszName
  211.  *  pchEaten        ULONG * in which to return the number of
  212.  *                  characters used in parsing pszDisplayName.
  213.  *  fValidate       BOOL indicating if we're to validate that the
  214.  *                  source exists first.
  215.  *
  216.  * Return Value:
  217.  *  HRESULT         NOERROR if successful, E_FAIL otherwise.
  218.  */
  219. STDMETHODIMP CIOleUILinkContainer::SetLinkSource(DWORD dwLink
  220.     , LPTSTR pszName, ULONG cchName, ULONG *pchEaten
  221.     , BOOL fValidate)
  222.     {
  223.     PCTenant        pTenant=(PCTenant)dwLink;
  224.     HRESULT         hr;
  225.     LPOLELINK       pIOleLink;
  226.     if (NULL==dwLink)
  227.         return ResultFromScode(E_FAIL);
  228.     //This is for use in GetLinkSource, below.
  229.     pTenant->m_fLinkAvail=FALSE;
  230.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  231.     if (FAILED(hr))
  232.         return hr;
  233.     hr=m_pDelIUILinks->SetLinkSource((DWORD)pIOleLink, pszName
  234.         , cchName, pchEaten, fValidate);
  235.     pIOleLink->Release();
  236.     if (FAILED(hr))
  237.         return hr;
  238.     //hr will be S_FALSE if link is unavailable.
  239.     pTenant->Repaint();
  240.     pTenant->m_fLinkAvail=(NOERROR==hr);
  241.     m_fDirty=TRUE;
  242.     return NOERROR;
  243.     }
  244. /*
  245.  * CIOleUILinkContainer::GetLinkSource
  246.  *
  247.  * Purpose:
  248.  *  Retrieves various strings and values for this link source.
  249.  *
  250.  * Parameters:
  251.  *  dwLink          DWORD identifying the object affected.
  252.  *  ppszName        LPTSTR * in which to return the new source
  253.  *                  name
  254.  *  pcchName        ULONG * in which to return the length of
  255.  *                  pszName
  256.  *  ppszFullLink    LPTSTR * in which to return the full name of
  257.  *                  the class of linked object.
  258.  *  ppszShortLink   LPTSTR * in which to return the short name of
  259.  *                  the class of linked object.
  260.  *  pfSourceAvail   BOOL * in which to return if this is an
  261.  *                  available link source.
  262.  *  pfSelected      BOOL * in which to return if this object is
  263.  *                  currently selected in the document.  This
  264.  *                  selects the item in the listbox for this object.
  265.  *
  266.  * Return Value:
  267.  *  HRESULT         NOERROR on success, error code otherwise.
  268.  */
  269. STDMETHODIMP CIOleUILinkContainer::GetLinkSource(DWORD dwLink
  270.     , LPTSTR *ppszName, ULONG *pcchName, LPTSTR *ppszFullLink
  271.     , LPTSTR *ppszShortLink, BOOL *pfSourceAvail, BOOL *pfSelected)
  272.     {
  273.     HRESULT         hr;
  274.     PCTenant        pTenant=(PCTenant)dwLink;
  275.     LPOLELINK       pIOleLink=NULL;
  276.     LPOLEOBJECT     pIOleObject=NULL;
  277.     LPMONIKER       pmk=NULL;
  278.     LPMONIKER       pmkFirst=NULL;
  279.     LPBC            pbc=NULL;
  280.     if (NULL==dwLink)
  281.         return ResultFromScode(E_FAIL);
  282.     //We know what this is from SetLinkSource
  283.     *pfSourceAvail=pTenant->m_fLinkAvail;
  284.     if (pfSelected)
  285.         *pfSelected=pTenant->FIsSelected();
  286.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  287.     if (FAILED(hr))
  288.         return hr;
  289.     hr=m_pDelIUILinks->GetLinkSource((DWORD)pIOleLink, ppszName
  290.         , pcchName, ppszFullLink, ppszShortLink, pfSourceAvail
  291.         , pfSelected);
  292.     pIOleLink->Release();
  293.     return hr;
  294.     }
  295. /*
  296.  * CIOleUILinkContainer::OpenLinkSource
  297.  *
  298.  * Purpose:
  299.  *  Asks the container to call DoVerb on this object with
  300.  *  OLEIVERB_SHOW.
  301.  *
  302.  * Parameters:
  303.  *  dwLink          DWORD identifying the linked object.
  304.  *
  305.  * Return Value:
  306.  *  HRESULT         Standard.
  307.  */
  308. STDMETHODIMP CIOleUILinkContainer::OpenLinkSource(DWORD dwLink)
  309.     {
  310.     PCTenant        pTenant=(PCTenant)dwLink;
  311.     pTenant->Activate(OLEIVERB_OPEN);
  312.     return NOERROR;
  313.     }
  314. /*
  315.  * CIOleUILinkContainer::UpdateLink
  316.  *
  317.  * Purpose:
  318.  *  Asks the container to update the link for this object.
  319.  *
  320.  * Parameters:
  321.  *  dwLink          DWORD identifying the linked object.
  322.  *  fErrorMessage   BOOL indicating if we can show errors.
  323.  *  fErrorAction    BOOL making no sense whatsoever.
  324.  *
  325.  * Return Value:
  326.  *  HRESULT         Standard.
  327.  */
  328. STDMETHODIMP CIOleUILinkContainer::UpdateLink(DWORD dwLink
  329.     , BOOL fErrorMessage, BOOL fErrorAction)
  330.     {
  331.     PCTenant        pTenant=(PCTenant)dwLink;
  332.     LPOLELINK       pIOleLink;
  333.     HRESULT         hr;
  334.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  335.     if (FAILED(hr))
  336.         return hr;
  337.     hr=m_pDelIUILinks->UpdateLink((DWORD)pIOleLink, fErrorMessage
  338.         , fErrorAction);
  339.     pTenant->Repaint();
  340.     pTenant->m_fLinkAvail=SUCCEEDED(hr);
  341.     pIOleLink->Release();
  342.     if (FAILED(hr))
  343.         {
  344.         if (fErrorMessage)
  345.             {
  346.             MessageBox(m_pPage->m_hWnd
  347.                 , TEXT("Could not update link."), TEXT("Patron")
  348.                 , MB_OK);
  349.             }
  350.         }
  351.     else
  352.         m_fDirty=TRUE;
  353.     return hr;
  354.     }
  355. /*
  356.  * CIOleUILinkContainer::CancelLink
  357.  *
  358.  * Purpose:
  359.  *  Requests that the container turn this linked object into a
  360.  *  static object.
  361.  *
  362.  * Parameters:
  363.  *  dwLink          DWORD identifying the linked object.
  364.  *
  365.  * Return Value:
  366.  *  HRESULT         Standard.
  367.  */
  368. STDMETHODIMP CIOleUILinkContainer::CancelLink(DWORD dwLink)
  369.     {
  370.     PCTenant        pTenant=(PCTenant)dwLink;
  371.     LPOLELINK       pIOleLink;
  372.     HRESULT         hr;
  373.     hr=GetObjectInterface(dwLink, IID_IOleLink, (PPVOID)&pIOleLink);
  374.     if (FAILED(hr))
  375.         return hr;
  376.     //This sets the source moniker to NULL.
  377.     m_pDelIUILinks->CancelLink((DWORD)pIOleLink);
  378.     pIOleLink->Release();
  379.     //Go change this object over to a static one.
  380.     pTenant->ConvertToStatic();
  381.     m_fDirty=TRUE;
  382.     return NOERROR;
  383.     }
  384. //PROTECTED FUNCTIONS INTERNAL TO CIOleUILinkContainer
  385. /*
  386.  * CIOleUILinkContainer::GetObjectInterface
  387.  * (Protected)
  388.  *
  389.  * Purpose:
  390.  *  Retrieves and interface pointer for the object identified by
  391.  *  dwLink
  392.  *
  393.  * Parameters:
  394.  *  dwLink          DWORD identifying the object
  395.  *  riid            REFIID of the interface desired.
  396.  *  ppv             PPVOID into which we return the pointer.
  397.  *
  398.  * Return Value:
  399.  *  HRESULT         NOERROR on success, error code otherwise.
  400.  */
  401. STDMETHODIMP CIOleUILinkContainer::GetObjectInterface(DWORD dwLink
  402.     , REFIID riid, PPVOID ppv)
  403.     {
  404.     PCTenant        pTenant=(PCTenant)dwLink;
  405.     LPUNKNOWN       pIUnknown;
  406.     HRESULT         hr;
  407.     pTenant->ObjectGet(&pIUnknown);
  408.     hr=pIUnknown->QueryInterface(riid, ppv);
  409.     pIUnknown->Release();
  410.     return hr;
  411.     }