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

Windows编程

开发平台:

Visual C++

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