home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / tutsamp / perclien / listsink.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-05  |  16.6 KB  |  498 lines

  1. /*+==========================================================================
  2.   File:      LISTSINK.CPP
  3.  
  4.   Summary:   Implementation file for the COPageListSink COM Object Class.
  5.              Connectable object notifications of PageList events are
  6.              handled by COPageListSink.
  7.  
  8.              COPageListSink offers a main IUnknown standard interface and
  9.              the IPageListSink custom interface (with the PageList related
  10.              event features). This multiple interface COM Object Class is
  11.              achieved via the technique of nested classes.  The
  12.              implementation of the IPageListSink interface is nested
  13.              inside the COPageListSink Class.
  14.  
  15.              For a comprehensive tutorial code tour of this module's
  16.              contents and offerings see the tutorial PERCLIEN.HTM
  17.              file. For more specific technical details on the internal
  18.              workings see the comments dispersed throughout the module's
  19.              source code.
  20.  
  21.   Classes:   COPageListSink.
  22.  
  23.   Functions: none.
  24.  
  25.   Origin:    5-20-97: atrent - Editor-inheritance from SINK.CPP in
  26.              the STOCLIEN Tutorial Code Sample. [Revised]
  27.  
  28. ----------------------------------------------------------------------------
  29.   This file is part of the Microsoft COM Tutorial Code Samples.
  30.  
  31.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  32.  
  33.   This source code is intended only as a supplement to Microsoft
  34.   Development Tools and/or on-line documentation.  See these other
  35.   materials for detailed information regarding Microsoft code samples.
  36.  
  37.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  38.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  39.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  40.   PARTICULAR PURPOSE.
  41. ==========================================================================+*/
  42.  
  43.  
  44. /*---------------------------------------------------------------------------
  45.   We include WINDOWS.H for all Win32 applications.
  46.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  47.   We include OLECTL.H because it has definitions for connectable objects.
  48.   We include APPUTIL.H because we will be building this application using
  49.     the convenient Virtual Window and Dialog classes and other
  50.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  51.   We include IPAGES.H and PAGEGUID.H for the common Page-related
  52.     Interface class, GUID, and CLSID specifications.
  53.   We include PAGFILE.H because it has the C++ class used for compound file
  54.     storage of PageList data.
  55.   We include LISTWIN.H because CGuiList creates and uses a CListWin to
  56.     encapsulate the standard list box control.
  57.   We include GUILIST.H because it declares the class for the main C++
  58.     object that can service the Sink events.
  59.   We include LISTSINK.H because of the class COPageListSink declarations.
  60. ---------------------------------------------------------------------------*/
  61. #include <windows.h>
  62. #include <ole2.h>
  63. #include <olectl.h>
  64. #include <apputil.h>
  65. #include <ipages.h>
  66. #include <pageguid.h>
  67. #include "pagefile.h"
  68. #include "listwin.h"
  69. #include "guilist.h"
  70. #include "listsink.h"
  71.  
  72.  
  73. /*---------------------------------------------------------------------------
  74.   COPageListSink's implementation of its main COM object class including
  75.   Constructor, Destructor, QueryInterface, AddRef, and Release.
  76. ---------------------------------------------------------------------------*/
  77.  
  78. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  79.   Method:   COPageListSink::COPageListSink
  80.  
  81.   Summary:  COPageListSink Constructor. Note the member initializer:
  82.             "m_ImpIPageListSink(this, pUnkOuter)" which is used to pass
  83.             the 'this' and pUnkOuter pointers of this constructor function
  84.             to the constructor in the instantiation of the implementation
  85.             of the CImpIPageListSink interface (which is nested inside
  86.             this present COPageListSink Object Class).
  87.  
  88.   Args:     IUnknown* pUnkOuter,
  89.               Pointer to the the outer Unknown.  NULL means this COM Object
  90.               is not being Aggregated.  Non NULL means it is being created
  91.               on behalf of an outside COM object that is reusing it via
  92.               aggregation.
  93.             CGuiList* pGuiList)
  94.               Pointer to the main C++ object that can service the
  95.               PageListSink events.
  96.  
  97.   Modifies: m_cRefs, m_pUnkOuter, m_pGuiList.
  98.  
  99.   Returns:  void
  100. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  101. COPageListSink::COPageListSink(
  102.   IUnknown* pUnkOuter,
  103.   CGuiList* pGuiList) :
  104.   m_ImpIPageListSink(this, pUnkOuter)
  105. {
  106.   // Zero the COM object's reference count.
  107.   m_cRefs = 0;
  108.  
  109.   // No AddRef necessary if non-NULL, as we're nested.
  110.   m_pUnkOuter = pUnkOuter;
  111.  
  112.   // Assign the pointer to the Sink service C++ object.
  113.   m_pGuiList = pGuiList;
  114.  
  115.   return;
  116. }
  117.  
  118.  
  119. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  120.   Method:   COPageListSink::~COPageListSink
  121.  
  122.   Summary:  COPageListSink Destructor.
  123.  
  124.   Args:     void
  125.  
  126.   Returns:  void
  127. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  128. COPageListSink::~COPageListSink(void)
  129. {
  130.   return;
  131. }
  132.  
  133.  
  134. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  135.   Method:   COPageListSink::QueryInterface
  136.  
  137.   Summary:  QueryInterface of the COPageListSink non-delegating
  138.             IUnknown implementation.
  139.  
  140.   Args:     REFIID riid,
  141.               [in] GUID of the Interface being requested.
  142.             PPVOID ppv)
  143.               [out] Address of the caller's pointer variable that will
  144.               receive the requested interface pointer.
  145.  
  146.   Returns:  HRESULT
  147. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  148. STDMETHODIMP COPageListSink::QueryInterface(
  149.                REFIID riid,
  150.                PPVOID ppv)
  151. {
  152.   HRESULT hr = E_NOINTERFACE;
  153.  
  154.   *ppv = NULL;
  155.  
  156.   if (IID_IUnknown == riid)
  157.     *ppv = this;
  158.   else if (IID_IPageListSink == riid)
  159.     *ppv = &m_ImpIPageListSink;
  160.  
  161.   if (NULL != *ppv)
  162.   {
  163.     // We've handed out a pointer to the interface so obey the COM rules
  164.     // and AddRef the reference count.
  165.     ((LPUNKNOWN)*ppv)->AddRef();
  166.     hr = NOERROR;
  167.   }
  168.  
  169.  
  170.   return (hr);
  171. }
  172.  
  173.  
  174. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  175.   Method:   COPageListSink::AddRef
  176.  
  177.   Summary:  AddRef of the COPageListSink non-delegating IUnknown
  178.             implementation.
  179.  
  180.   Args:     void
  181.  
  182.   Modifies: m_cRefs.
  183.  
  184.   Returns:  ULONG
  185.               New value of m_cRefs (COM object's reference count).
  186. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  187. STDMETHODIMP_(ULONG) COPageListSink::AddRef(void)
  188. {
  189.   ULONG cRefs;
  190.  
  191.   cRefs = ++m_cRefs;
  192.  
  193.   return cRefs;
  194. }
  195.  
  196.  
  197. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  198.   Method:   COPageListSink::Release
  199.  
  200.   Summary:  Release of the COPageListSink non-delegating IUnknown
  201.             implementation.
  202.  
  203.   Args:     void
  204.  
  205.   Modifies: m_cRefs.
  206.  
  207.   Returns:  ULONG
  208.               New value of m_cRefs (COM object's reference count).
  209. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  210. STDMETHODIMP_(ULONG) COPageListSink::Release(void)
  211. {
  212.   ULONG cRefs;
  213.  
  214.   cRefs = --m_cRefs;
  215.  
  216.   if (0 == cRefs)
  217.   {
  218.     // We artificially bump the main ref count to prevent reentrancy
  219.     // via the main object destructor.  Not really needed in this
  220.     // COPageListSink but a good practice because we are aggregatable and
  221.     // may at some point in the future add something entertaining like
  222.     // some Releases to the COPageListSink destructor.
  223.     m_cRefs++;
  224.     delete this;
  225.   }
  226.  
  227.   return cRefs;
  228. }
  229.  
  230.  
  231. /*---------------------------------------------------------------------------
  232.   COPageListSink's nested implementation of the IPageListSink interface
  233.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  234.   Loaded, Saved, Cleared, PageAdded, PageDeleted, and PageSet. Methods in
  235.   this interface are called by COM objects on the server side to send
  236.   event notifications to the client.
  237. ---------------------------------------------------------------------------*/
  238.  
  239. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  240.   Method:   COPageListSink::CImpIPageListSink::CImpIPageListSink
  241.  
  242.   Summary:  Constructor for the CImpIPageListSink interface instantiation.
  243.  
  244.   Args:     COPageListSink* pCO,
  245.               Back pointer to the parent outer object.
  246.             IUnknown* pUnkOuter
  247.               Pointer to the outer Unknown.  For delegation.
  248.  
  249.   Modifies: m_pCO, m_pUnkOuter.
  250.  
  251.   Returns:  void
  252. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  253. COPageListSink::CImpIPageListSink::CImpIPageListSink(
  254.   COPageListSink* pCO,
  255.   IUnknown* pUnkOuter)
  256. {
  257.   // Init the main object Pointer to point to the parent object.
  258.   m_pCO = pCO;
  259.  
  260.   // Init the CImpIPageListSink interface's delegating Unknown pointer. We
  261.   // use the main object pointer for IUnknown delegation here if we are
  262.   // not being aggregated.  If we are being aggregated we use the supplied
  263.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  264.   // assignment requires no AddRef because the CImpIPageListSink lifetime
  265.   // is quaranteed by the lifetime of the parent object in which
  266.   // CImpIPageListSink is nested.
  267.   if (NULL == pUnkOuter)
  268.     m_pUnkOuter = pCO;
  269.   else
  270.     m_pUnkOuter = pUnkOuter;
  271.  
  272.   return;
  273. }
  274.  
  275.  
  276. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  277.   Method:   COPageListSink::CImpIPageListSink::~CImpIPageListSink
  278.  
  279.   Summary:  Destructor for the CImpIPageListSink interface instantiation.
  280.  
  281.   Args:     void
  282.  
  283.   Returns:  void
  284. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  285. COPageListSink::CImpIPageListSink::~CImpIPageListSink(void)
  286. {
  287.   return;
  288. }
  289.  
  290.  
  291. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  292.   Method:   COPageListSink::CImpIPageListSink::QueryInterface
  293.  
  294.   Summary:  The QueryInterface IUnknown member of this IPageListSink
  295.             interface implementation that delegates to m_pUnkOuter,
  296.             whatever it is.
  297.  
  298.   Args:     REFIID riid,
  299.               [in] GUID of the Interface being requested.
  300.             PPVOID ppv)
  301.               [out] Address of the caller's pointer variable that will
  302.               receive the requested interface pointer.
  303.  
  304.   Returns:  HRESULT
  305.               Returned by the delegated outer QueryInterface call.
  306. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  307. STDMETHODIMP COPageListSink::CImpIPageListSink::QueryInterface(
  308.                REFIID riid,
  309.                PPVOID ppv)
  310. {
  311.   // Delegate this call to the outer object's QueryInterface.
  312.   return m_pUnkOuter->QueryInterface(riid, ppv);
  313. }
  314.  
  315.  
  316. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  317.   Method:   COPageListSink::CImpIPageListSink::AddRef
  318.  
  319.   Summary:  The AddRef IUnknown member of this IPageListSink interface
  320.             implementation that delegates to m_pUnkOuter, whatever it is.
  321.  
  322.   Args:     void
  323.  
  324.   Returns:  ULONG
  325.               Returned by the delegated outer AddRef call.
  326. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  327. STDMETHODIMP_(ULONG) COPageListSink::CImpIPageListSink::AddRef(void)
  328. {
  329.   // Delegate this call to the outer object's AddRef.
  330.   return m_pUnkOuter->AddRef();
  331. }
  332.  
  333.  
  334. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  335.   Method:   COPageListSink::CImpIPageListSink::Release
  336.  
  337.   Summary:  The Release IUnknown member of this IPageListSink interface
  338.             implementation that delegates to m_pUnkOuter, whatever it is.
  339.  
  340.   Args:     void
  341.  
  342.   Returns:  ULONG
  343.               Returned by the delegated outer Release call.
  344. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  345. STDMETHODIMP_(ULONG) COPageListSink::CImpIPageListSink::Release(void)
  346. {
  347.   // Delegate this call to the outer object's Release.
  348.   return m_pUnkOuter->Release();
  349. }
  350.  
  351.  
  352. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  353.   Method:   COPageListSink::CImpIPageListSink::Loaded
  354.  
  355.   Summary:  The COPageList object's list data was loaded from a
  356.             client's compound file.
  357.  
  358.   Args:     void
  359.  
  360.   Returns:  HRESULT
  361.               Standard result code. NOERROR for success.
  362. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  363. STDMETHODIMP COPageListSink::CImpIPageListSink::Loaded(
  364.                void)
  365. {
  366.   HRESULT hr;
  367.  
  368.   // We have been notified that a load was done. A whole new array of
  369.   // PageList data must be displayed in the ListWin window of this client.
  370.   hr = m_pCO->m_pGuiList->Show(0);
  371.  
  372.   return hr;
  373. }
  374.  
  375.  
  376. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  377.   Method:   COPageListSink::CImpIPageListSink::Saved
  378.  
  379.   Summary:  The COPageList object's PageList data was saved to a
  380.             client's compound file.
  381.  
  382.   Args:     void
  383.  
  384.   Returns:  HRESULT
  385.               Standard result code. NOERROR for success.
  386. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  387. STDMETHODIMP COPageListSink::CImpIPageListSink::Saved(
  388.                void)
  389. {
  390.   HRESULT hr = E_NOTIMPL;
  391.  
  392.   // For future evolution.
  393.  
  394.   return hr;
  395. }
  396.  
  397.  
  398. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  399.   Method:   COPageListSink::CImpIPageListSink::Cleared
  400.  
  401.   Summary:  Another client has cleared the content of the PageList.
  402.  
  403.   Args:     void
  404.  
  405.   Returns:  HRESULT
  406.               Standard result code. NOERROR for success.
  407. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  408. STDMETHODIMP COPageListSink::CImpIPageListSink::Cleared(
  409.                void)
  410. {
  411.   HRESULT hr;
  412.  
  413.   // We have been notified that a clear was done. An empty array of
  414.   // PageList data must be displayed in the ListWin window of this client.
  415.   hr = m_pCO->m_pGuiList->Show(0);
  416.  
  417.   return hr;
  418. }
  419.  
  420.  
  421. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  422.   Method:   COPageListSink::CImpIPageListSink::PageAdded
  423.  
  424.   Summary:  A page was added to the page list.
  425.  
  426.   Args:     INT iPage
  427.               The page number of the newly added page.
  428.  
  429.   Returns:  HRESULT
  430.               Standard result code. NOERROR for success.
  431. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  432. STDMETHODIMP COPageListSink::CImpIPageListSink::PageAdded(
  433.                INT iPage)
  434. {
  435.   HRESULT hr;
  436.  
  437.   // We have been notified that a new page was added. In this simple
  438.   // sample app the entire array is reshown. A more efficient action
  439.   // would be to call CListWin::InsertFmt to insert/add only the
  440.   // list item that was added to the list.
  441.   hr = m_pCO->m_pGuiList->Show(iPage);
  442.  
  443.   return hr;
  444. }
  445.  
  446.  
  447. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  448.   Method:   COPageListSink::CImpIPageListSink::PageDeleted
  449.  
  450.   Summary:  A page was deleted from the page list.
  451.  
  452.   Args:     INT iPage
  453.               Page number of the page that was deleted.
  454.  
  455.   Returns:  HRESULT
  456.               Standard result code. NOERROR for success.
  457. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  458. STDMETHODIMP COPageListSink::CImpIPageListSink::PageDeleted(
  459.                INT iPage)
  460. {
  461.   HRESULT hr;
  462.  
  463.   // We have been notified that a page was deleted. In this simple
  464.   // sample app the entire array is reshown. A more efficient action
  465.   // would be to explicitly call CListWin (using the LB_DELETESTRING
  466.   // message) to only the delete the display line for the item
  467.   // that was deleted in COPageList.
  468.   hr = m_pCO->m_pGuiList->Show(iPage);
  469.  
  470.   return hr;
  471. }
  472.  
  473.  
  474. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  475.   Method:   COPageListSink::CImpIPageListSink::PageSet
  476.  
  477.   Summary:  An existing page was retitled.
  478.  
  479.   Args:     INT iPage
  480.               Page number of the page that was retitled.
  481.  
  482.   Returns:  HRESULT
  483.               Standard result code. NOERROR for success.
  484. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  485. STDMETHODIMP COPageListSink::CImpIPageListSink::PageSet(
  486.                INT iPage)
  487. {
  488.   HRESULT hr;
  489.  
  490.   // We have been notified that the current page was retitled.
  491.   // In this simple sample app the entire array is reshown. A more
  492.   // efficient action would be to explicitly call CListWin (using the
  493.   // iPage given) to only re-display the display line that was changed.
  494.   hr = m_pCO->m_pGuiList->Show(iPage);
  495.  
  496.   return hr;
  497. }
  498.