home *** CD-ROM | disk | FTP | other *** search
/ PC Press 1997 July / Sezamfile97_2.iso / windows / program / activex / axtsamp.exe / TSBRANCH.EXE / FRESERVE / FACTORY.CPP < prev    next >
C/C++ Source or Header  |  1996-12-29  |  15KB  |  473 lines

  1. /*+==========================================================================
  2.   File:      FACTORY.CPP
  3.  
  4.   Summary:   Implementation file for the class factories of the FRESERVE
  5.              server.  This server provides the Ball COM component. For
  6.              this component, IClassFactory is implemented in an
  7.              appropriate class factory COM object: CFBall. The COM
  8.              component that can be manufactured by this server is known
  9.              outside the server by its CLSID: CLSID_DllBall.
  10.  
  11.              For a comprehensive tutorial code tour of this module's
  12.              contents and offerings see the tutorial FRESERVE.HTM
  13.              file. For more specific technical details on the internal
  14.              workings see the comments dispersed throughout the module's
  15.              source code.
  16.  
  17.   Classes:   CFBall.
  18.  
  19.   Functions: .
  20.  
  21.   Origin:    4-6-96: atrent - Editor-inheritance from CAR.CPP in
  22.                the DLLSERVE Tutorial Code Sample.
  23.  
  24. ----------------------------------------------------------------------------
  25.   This file is part of the Microsoft ActiveX Tutorial Code Samples.
  26.  
  27.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  28.  
  29.   This source code is intended only as a supplement to Microsoft
  30.   Development Tools and/or on-line documentation.  See these other
  31.   materials for detailed information regarding Microsoft code samples.
  32.  
  33.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  34.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  35.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  36.   PARTICULAR PURPOSE.
  37. ==========================================================================+*/
  38.  
  39. /*---------------------------------------------------------------------------
  40.   We include WINDOWS.H for all Win32 applications.
  41.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  42.   We include APPUTIL.H because we will be building this DLL using
  43.     the convenient Virtual Window and Dialog classes and other
  44.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  45.   We include IBALL.H and BALLGUID.H for the common ball-related Interface
  46.     class, GUID, and CLSID specifications.
  47.   We include SERVER.H because it has the necessary internal class and
  48.     resource definitions for this DLL.
  49.   We include FACTORY.H because it has the necessary internal class factory
  50.     declarations for this DLL component server.  Those factories we will be
  51.     implementing in this module.
  52.   We include BALL.H, for the object class declarations for the COBall
  53.     COM object.
  54. ---------------------------------------------------------------------------*/
  55. #include <windows.h>
  56. #include <ole2.h>
  57. #include <apputil.h>
  58. #include <iball.h>
  59. #include <ballguid.h>
  60. #include "server.h"
  61. #include "factory.h"
  62. #include "ball.h"
  63.  
  64. /*---------------------------------------------------------------------------
  65.   Implementation the CFBall Class Factory.  CFBall is the COM
  66.   object class for the Class Factory that can manufacture COBall
  67.   COM Components.
  68. ---------------------------------------------------------------------------*/
  69.  
  70. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  71.   Method:   CFBall::CFBall
  72.  
  73.   Summary:  CFBall Constructor. Note the member initializer:
  74.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  75.             to pass the 'this', pUnkOuter, and pServer pointers of this
  76.             constructor function to the constructor executed in the
  77.             instantiation of the CImpIClassFactory interface whose
  78.             implementation is nested inside this present object class.
  79.  
  80.   Args:     IUnknown* pUnkOuter,
  81.               Pointer to the the outer Unknown.  NULL means this COM Object
  82.               is not being Aggregated.  Non NULL means it is being created
  83.               on behalf of an outside COM object that is reusing it via
  84.               aggregation.
  85.             CServer* pServer)
  86.               Pointer to the server's control object.
  87.  
  88.   Modifies: m_cRefs, m_pUnkOuter.
  89.  
  90.   Returns:  void
  91. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  92. CFBall::CFBall(
  93.   IUnknown* pUnkOuter,
  94.   CServer* pServer) :
  95.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  96. {
  97.   // Zero the COM object's reference count.
  98.   m_cRefs = 0;
  99.  
  100.   // No AddRef necessary if non-NULL, as we're nested.
  101.   m_pUnkOuter = pUnkOuter;
  102.  
  103.   // Init the pointer to the server control object.
  104.   m_pServer = pServer;
  105.  
  106.   return;
  107. }
  108.  
  109.  
  110. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  111.   Method:   CFBall::~CFBall
  112.  
  113.   Summary:  CFBall Destructor.
  114.  
  115.   Args:     void
  116.  
  117.   Modifies: .
  118.  
  119.   Returns:  void
  120. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  121. CFBall::~CFBall(void)
  122. {
  123.   return;
  124. }
  125.  
  126.  
  127. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  128.   Method:   CFBall::QueryInterface
  129.  
  130.   Summary:  QueryInterface of the CFBall non-delegating
  131.             IUnknown implementation.
  132.  
  133.   Args:     REFIID riid,
  134.               [in] GUID of the Interface being requested.
  135.             PPVOID ppv)
  136.               [out] Address of the caller's pointer variable that will
  137.               receive the requested interface pointer.
  138.  
  139.   Modifies: .
  140.  
  141.   Returns:  HRESULT
  142. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  143. STDMETHODIMP CFBall::QueryInterface(
  144.                REFIID riid,
  145.                PPVOID ppv)
  146. {
  147.   HRESULT hr = E_NOINTERFACE;
  148.  
  149.   if (OwnThis())
  150.   {
  151.     *ppv = NULL;
  152.  
  153.     if (IID_IUnknown == riid)
  154.       *ppv = this;
  155.     else if (IID_IClassFactory == riid)
  156.       *ppv = &m_ImpIClassFactory;
  157.  
  158.     if (NULL != *ppv)
  159.     {
  160.       // We've handed out a pointer to the interface so obey the COM rules
  161.       // and AddRef the reference count.
  162.       ((LPUNKNOWN)*ppv)->AddRef();
  163.       hr = NOERROR;
  164.     }
  165.  
  166.     UnOwnThis();
  167.   }
  168.  
  169.   return (hr);
  170. }
  171.  
  172.  
  173. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  174.   Method:   CFBall::AddRef
  175.  
  176.   Summary:  AddRef of the CFBall non-delegating IUnknown implementation.
  177.  
  178.   Args:     void
  179.  
  180.   Modifies: m_cRefs.
  181.  
  182.   Returns:  ULONG
  183.               New value of m_cRefs (COM object's reference count).
  184. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  185. STDMETHODIMP_(ULONG) CFBall::AddRef(void)
  186. {
  187.   ULONG cRefs;
  188.  
  189.   if (OwnThis())
  190.   {
  191.     cRefs = ++m_cRefs;
  192.  
  193.     UnOwnThis();
  194.   }
  195.  
  196.   return cRefs;
  197. }
  198.  
  199.  
  200. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  201.   Method:   CFBall::Release
  202.  
  203.   Summary:  Release of the CFBall non-delegating IUnknown implementation.
  204.  
  205.   Args:     void
  206.  
  207.   Modifies: m_cRefs.
  208.  
  209.   Returns:  ULONG
  210.               New value of m_cRefs (COM object's reference count).
  211. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  212. STDMETHODIMP_(ULONG) CFBall::Release(void)
  213. {
  214.   ULONG cRefs;
  215.  
  216.   if (OwnThis())
  217.   {
  218.     cRefs = --m_cRefs;
  219.  
  220.     if (0 == cRefs)
  221.     {
  222.       // We've reached a zero reference count for this COM object.
  223.       // So we tell the server housing to decrement its global object
  224.       // count so that the server will be unloaded if appropriate.
  225.       if (NULL != m_pServer)
  226.         m_pServer->ObjectsDown();
  227.  
  228.       // We artificially bump the main ref count to prevent reentrancy
  229.       // via the main object destructor.  Not really needed in this
  230.       // CFBall but a good practice because we are aggregatable and
  231.       // may at some point in the future add something entertaining like
  232.       // some Releases to the CFBall destructor.
  233.       m_cRefs++;
  234.       UnOwnThis();
  235.       delete this;
  236.     }
  237.     else
  238.       UnOwnThis();
  239.   }
  240.  
  241.   return cRefs;
  242. }
  243.  
  244.  
  245. /*---------------------------------------------------------------------------
  246.   CFBall's nested implementation of the IClassFactory interface
  247.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  248.   CreateInstance, and LockServer methods.
  249. ---------------------------------------------------------------------------*/
  250.  
  251. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  252.   Method:   CFBall::CImpIClassFactory::CImpIClassFactory
  253.  
  254.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  255.  
  256.   Args:     CFBall* pBackObj,
  257.               Back pointer to the parent outer object.
  258.             IUnknown* pUnkOuter,
  259.               Pointer to the outer Unknown.  For delegation.
  260.             CServer* pServer)
  261.               Pointer to the server's control object.
  262.  
  263.   Modifies: m_pBackObj, m_pUnkOuter, m_pServer.
  264.  
  265.   Returns:  void
  266. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  267. CFBall::CImpIClassFactory::CImpIClassFactory(
  268.   CFBall* pBackObj,
  269.   IUnknown* pUnkOuter,
  270.   CServer* pServer)
  271. {
  272.   // Init the Back Object Pointer to point to the parent object.
  273.   m_pBackObj = pBackObj;
  274.  
  275.   // Init the pointer to the server control object.
  276.   m_pServer = pServer;
  277.  
  278.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  279.   // We use the Back Object pointer for IUnknown delegation here if we are
  280.   // not being aggregated.  If we are being aggregated we use the supplied
  281.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  282.   // assignment requires no AddRef because the CImpIClassFactory lifetime is
  283.   // quaranteed by the lifetime of the parent object in which
  284.   // CImpIClassFactory is nested.
  285.   if (NULL == pUnkOuter)
  286.     m_pUnkOuter = pBackObj;
  287.   else
  288.     m_pUnkOuter = pUnkOuter;
  289.  
  290.   return;
  291. }
  292.  
  293.  
  294. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  295.   Method:   CFBall::CImpIClassFactory::~CImpIClassFactory
  296.  
  297.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  298.  
  299.   Args:     void
  300.  
  301.   Modifies: .
  302.  
  303.   Returns:  void
  304. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  305. CFBall::CImpIClassFactory::~CImpIClassFactory(void)
  306. {
  307.   return;
  308. }
  309.  
  310.  
  311. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  312.   Method:   CFBall::CImpIClassFactory::QueryInterface
  313.  
  314.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  315.             interface implementation that delegates to m_pUnkOuter,
  316.             whatever it is.
  317.  
  318.   Args:     REFIID riid,
  319.               [in] GUID of the Interface being requested.
  320.             PPVOID ppv)
  321.               [out] Address of the caller's pointer variable that will
  322.               receive the requested interface pointer.
  323.  
  324.   Modifies: .
  325.  
  326.   Returns:  HRESULT
  327.               Returned by the delegated outer QueryInterface call.
  328. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  329. STDMETHODIMP CFBall::CImpIClassFactory::QueryInterface(
  330.                REFIID riid,
  331.                PPVOID ppv)
  332. {
  333.   // Delegate this call to the outer object's QueryInterface.
  334.   return m_pUnkOuter->QueryInterface(riid, ppv);
  335. }
  336.  
  337.  
  338. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  339.   Method:   CFBall::CImpIClassFactory::AddRef
  340.  
  341.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  342.             implementation that delegates to m_pUnkOuter, whatever it is.
  343.  
  344.   Args:     void
  345.  
  346.   Modifies: .
  347.  
  348.   Returns:  ULONG
  349.               Returned by the delegated outer AddRef call.
  350. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  351. STDMETHODIMP_(ULONG) CFBall::CImpIClassFactory::AddRef(void)
  352. {
  353.   // Delegate this call to the outer object's AddRef.
  354.   return m_pUnkOuter->AddRef();
  355. }
  356.  
  357.  
  358. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  359.   Method:   CFBall::CImpIClassFactory::Release
  360.  
  361.   Summary:  The Release IUnknown member of this IClassFactory interface
  362.             implementation that delegates to m_pUnkOuter, whatever it is.
  363.  
  364.   Args:     void
  365.  
  366.   Modifies: .
  367.  
  368.   Returns:  ULONG
  369.               Returned by the delegated outer Release call.
  370. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  371. STDMETHODIMP_(ULONG) CFBall::CImpIClassFactory::Release(void)
  372. {
  373.   // Delegate this call to the outer object's Release.
  374.   return m_pUnkOuter->Release();
  375. }
  376.  
  377.  
  378. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  379.   Method:   CFBall::CImpIClassFactory::CreateInstance
  380.  
  381.   Summary:  The CreateInstance member method of this IClassFactory
  382.             interface implementation.  Creates an instance of the COBall
  383.             COM component.
  384.  
  385.   Args:     IUnknown* pUnkOuter,
  386.               [in] Pointer to the controlling IUnknown.
  387.             REFIID riid,
  388.               [in] GUID of the Interface being requested.
  389.             PPVOID ppvCob)
  390.               [out] Address of the caller's pointer variable that will
  391.               receive the requested interface pointer.
  392.  
  393.   Modifies: .
  394.  
  395.   Returns:  HRESULT
  396.               Standard result code.
  397. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  398. STDMETHODIMP CFBall::CImpIClassFactory::CreateInstance(
  399.                IUnknown* pUnkOuter,
  400.                REFIID riid,
  401.                PPVOID ppv)
  402. {
  403.   HRESULT hr = E_FAIL;
  404.   COBall* pCob = NULL;
  405.  
  406.   // NULL the output pointer.
  407.   *ppv = NULL;
  408.  
  409.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  410.   // the COM rules state the IUnknown interface MUST also be concomitantly
  411.   // be requested.  If it is not so requested (riid != IID_IUnknown) then
  412.   // an error must be returned indicating that no aggregate creation of
  413.   // the CFBall COM Object can be performed.
  414.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  415.     hr = CLASS_E_NOAGGREGATION;
  416.   else
  417.   {
  418.     // Instantiate a COBall COM Object.
  419.     pCob = new COBall(pUnkOuter, m_pServer);
  420.     if (NULL != pCob)
  421.     {
  422.       // We initially created the new COM object so tell the server
  423.       // to increment its global server object count to help ensure
  424.       // that the server remains loaded until this partial creation
  425.       // of a COM component is completed.
  426.       m_pServer->ObjectsUp();
  427.  
  428.       // We QueryInterface this new COM Object not only to deposit the
  429.       // main interface pointer to the caller's pointer variable, but to
  430.       // also automatically bump the Reference Count on the new COM
  431.       // Object after handing out this reference to it.
  432.       hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  433.       if (FAILED(hr))
  434.       {
  435.         m_pServer->ObjectsDown();
  436.         delete pCob;
  437.       }
  438.     }
  439.     else
  440.       hr = E_OUTOFMEMORY;
  441.   }
  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:   CFBall::CImpIClassFactory::LockServer
  449.  
  450.   Summary:  The LockServer member method of this IClassFactory interface
  451.             implementation.
  452.  
  453.   Args:     BOOL fLock)
  454.               [in] Flag determining whether to Lock or Unlock the server.
  455.  
  456.   Modifies: .
  457.  
  458.   Returns:  HRESULT
  459.               Standard result code.
  460. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  461. STDMETHODIMP CFBall::CImpIClassFactory::LockServer(
  462.                BOOL fLock)
  463. {
  464.   HRESULT hr = NOERROR;
  465.  
  466.   if (fLock)
  467.     m_pServer->Lock();
  468.   else
  469.     m_pServer->Unlock();
  470.  
  471.   return hr;
  472. }
  473.