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

Windows编程

开发平台:

Visual C++

  1. /*+==========================================================================
  2.   File:      CRUCAR.CPP
  3.   Summary:   Implementation file for the aggregatable COLicCruiseCar COM
  4.              object class.
  5.              CRUCAR showcases the construction of the COLicCruiseCar COM
  6.              object class with the IUnknown, ICar, and ICruise interfaces.
  7.              This is done through Aggregation reuse of COCar's ICar
  8.              interface features.  COCar is provided by a separate COM
  9.              server (DLLSERVE).
  10.              For a comprehensive tutorial code tour of this module's
  11.              contents and offerings see the tutorial DLLSERVE.HTM file.
  12.              For more specific technical details on the internal workings
  13.              see the comments dispersed throughout the module's source code.
  14.   Classes:   COLicCruiseCar.
  15.   Functions: none.
  16.   Origin:    10-5-95: atrent - Editor-inheritance from CRUCAR.CPP in
  17.                the DLLSERVE Tutorial Code Sample.
  18. ----------------------------------------------------------------------------
  19.   This file is part of the Microsoft COM Tutorial Code Samples.
  20.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  21.   This source code is intended only as a supplement to Microsoft
  22.   Development Tools and/or on-line documentation.  See these other
  23.   materials for detailed information regarding Microsoft code samples.
  24.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  25.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  26.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  27.   PARTICULAR PURPOSE.
  28. ==========================================================================+*/
  29. /*---------------------------------------------------------------------------
  30.   We include WINDOWS.H for all Win32 applications.
  31.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  32.   We include APPUTIL.H because we will be building this application using
  33.     the convenient Virtual Window and Dialog classes and other
  34.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  35.   We include ICARS.H and CARGUIDS.H for the common car-related Interface
  36.     class, GUID, and CLSID specifications.
  37.   We include SERVER.H because it has the necessary internal class and
  38.     resource definitions for this DLL.
  39.   We include CRUCAR.H because it has the class COLicCruiseCar declarations.
  40. ---------------------------------------------------------------------------*/
  41. #include <windows.h>
  42. #include <ole2.h>
  43. #include <apputil.h>
  44. #include <icars.h>
  45. #include <carguids.h>
  46. #include "server.h"
  47. #include "crucar.h"
  48. /*---------------------------------------------------------------------------
  49.   COLicCruiseCar's implementation of its main COM object class including
  50.   Constructor, Destructor, QueryInterface, AddRef, and Release.
  51. ---------------------------------------------------------------------------*/
  52. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  53.   Method:   COLicCruiseCar::COLicCruiseCar
  54.   Summary:  COLicCruiseCar Constructor. Note the member initializer:
  55.             "m_ImpICruise(this, pUnkOuter)" which is used to pass the
  56.             'this' and pUnkOuter pointers of this constructor function
  57.             to the constructor in the instantiation of the implementation
  58.             of the CImpICruise interface (which is nested inside this
  59.             present COLicCruiseCar Object Class).
  60.   Args:     IUnknown* pUnkOuter,
  61.               Pointer to the the outer Unknown.  NULL means this COM Object
  62.               is not being Aggregated.  Non NULL means it is being created
  63.               on behalf of an outside COM object that is reusing it via
  64.               aggregation.
  65.             CServer* pServer)
  66.               Pointer to the server's control object.
  67.   Modifies: m_cRefs, m_pUnkOuter.
  68.   Returns:  void
  69. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  70. COLicCruiseCar::COLicCruiseCar(
  71.   IUnknown* pUnkOuter,
  72.   CServer* pServer) :
  73.   m_ImpICruise(this, pUnkOuter)
  74. {
  75.   // Zero the COM object's reference count.
  76.   m_cRefs = 0;
  77.   // No AddRef necessary if non-NULL, as this present COM object's lifetime
  78.   // is totally coupled with the controlling Outer object's lifetime.
  79.   m_pUnkOuter = pUnkOuter;
  80.   // Zero the pointer to the aggregated COCar object's IUnknown
  81.   // interface (for delegation of IUnknown calls to it).
  82.   m_pUnkCar = NULL;
  83.   // Assign the pointer to the server's control object.
  84.   m_pServer = pServer;
  85.   LOGF1("P: COLicCruiseCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  86.   return;
  87. }
  88. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  89.   Method:   COLicCruiseCar::~COLicCruiseCar
  90.   Summary:  COLicCruiseCar Destructor.
  91.   Args:     void
  92.   Modifies: .
  93.   Returns:  void
  94. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  95. COLicCruiseCar::~COLicCruiseCar(void)
  96. {
  97.   LOG("P: COLicCruiseCar::Destructor.");
  98.   RELEASE_INTERFACE(m_pUnkCar);
  99.   return;
  100. }
  101. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  102.   Method:   COLicCruiseCar::Init
  103.   Summary:  COLicCruiseCar Initialization method.
  104.   Args:     void
  105.   Modifies: m_pUnkCar, m_pICar, m_cRefs.
  106.   Returns:  HRESULT
  107.               Standard result code. NOERROR for success.
  108. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  109. HRESULT COLicCruiseCar::Init(void)
  110. {
  111.   HRESULT hr;
  112.   LOG("P: COLicCruiseCar::Init.");
  113.   // Set up the right pIUnknown for delegation.  If we are being
  114.   // aggregated then we pass the pUnkOuter in turn to any COM objects
  115.   // that we are aggregating.  m_pUnkOuter was set in the Constructor.
  116.   IUnknown* pUnkOuter = (NULL == m_pUnkOuter) ? this : m_pUnkOuter;
  117.   // We create an instance of the COCar object and do this via the
  118.   // Aggregation reuse technique.  Note we pass pUnkOuter as the
  119.   // Aggregation pointer.  It is the 'this' pointer to this present
  120.   // LicCruiseCar object if we are not being aggregated; otherwise it is
  121.   // the pointer to the outermost object's controlling IUnknown.  Following
  122.   // the rules of Aggregation we must ask for an IID_IUnknown interface.
  123.   // We cache the requested  pointer to the IUnknown of the new COCar COM
  124.   // object for later use in delegating IUnknown calls.
  125.   hr = CoCreateInstance(
  126.          CLSID_DllCar,
  127.          pUnkOuter,
  128.          CLSCTX_INPROC_SERVER,
  129.          IID_IUnknown,
  130.          (PPVOID)&m_pUnkCar);
  131.   if (SUCCEEDED(hr))
  132.   {
  133.     LOG("P: COLicCruiseCar::Init (New Aggregation of COCar) Succeeded.");
  134.   }
  135.   else
  136.   {
  137.     LOG("P: COLicCruiseCar::Init (New Aggregation of COCar) Failed.");
  138.   }
  139.   return (hr);
  140. }
  141. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  142.   Method:   COLicCruiseCar::QueryInterface
  143.   Summary:  QueryInterface of the COLicCruiseCar non-delegating
  144.             IUnknown implementation.
  145.   Args:     REFIID riid,
  146.               [in] GUID of the Interface being requested.
  147.             PPVOID ppv)
  148.               [out] Address of the caller's pointer variable that will
  149.               receive the requested interface pointer.
  150.   Modifies: .
  151.   Returns:  HRESULT
  152. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  153. STDMETHODIMP COLicCruiseCar::QueryInterface(
  154.                REFIID riid,
  155.                PPVOID ppv)
  156. {
  157.   HRESULT hr = E_NOINTERFACE;
  158.   *ppv = NULL;
  159.   if (IID_IUnknown == riid)
  160.   {
  161.     *ppv = this;
  162.     LOG("P: COLicCruiseCar::QueryInterface. 'this' pIUnknown returned.");
  163.   }
  164.   else if (IID_ICruise == riid)
  165.   {
  166.     // This ICruise interface is implemented in this COLicCruiseCar object
  167.     // and might be called a native interface of COLicCruiseCar.
  168.     *ppv = &m_ImpICruise;
  169.     LOG("P: COLicCruiseCar::QueryInterface. pICruise returned.");
  170.   }
  171.   if (NULL != *ppv)
  172.   {
  173.     // We've handed out a pointer to an interface so obey the COM rules
  174.     //   and AddRef its reference count.
  175.     ((LPUNKNOWN)*ppv)->AddRef();
  176.     hr = NOERROR;
  177.   }
  178.   else if (IID_ICar == riid)
  179.   {
  180.     LOG("P: COLicCruiseCar::QueryInterface. ICar delegating.");
  181.     // We didn't implement the ICar interface in this COLicCruiseCar object.
  182.     // The aggregated inner COCar object is contributing the ICar interface
  183.     // to this present composite or aggregating LicCruiseCar object. So, to
  184.     // satisfy a QI request for the ICar interface, we delegate the
  185.     // QueryInterface to the inner object's principal IUnknown.
  186.     hr = m_pUnkCar->QueryInterface(riid, ppv);
  187.   }
  188.   return (hr);
  189. }
  190. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  191.   Method:   COLicCruiseCar::AddRef
  192.   Summary:  AddRef of the COLicCruiseCar non-delegating IUnknown
  193.             implementation.
  194.   Args:     void
  195.   Modifies: m_cRefs.
  196.   Returns:  ULONG
  197.               New value of m_cRefs (COM object's reference count).
  198. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  199. STDMETHODIMP_(ULONG) COLicCruiseCar::AddRef(void)
  200. {
  201.   m_cRefs++;
  202.   LOGF1("P: COLicCruiseCar::AddRef. New cRefs=%i.", m_cRefs);
  203.   return m_cRefs;
  204. }
  205. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  206.   Method:   COLicCruiseCar::Release
  207.   Summary:  Release of the COLicCruiseCar non-delegating IUnknown
  208.             implementation.
  209.   Args:     void
  210.   Modifies: m_cRefs.
  211.   Returns:  ULONG
  212.               New value of m_cRefs (COM object's reference count).
  213. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  214. STDMETHODIMP_(ULONG) COLicCruiseCar::Release(void)
  215. {
  216.   ULONG ulCount = --m_cRefs;
  217.   LOGF1("P: COLicCruiseCar::Release. New cRefs=%i.", m_cRefs);
  218.   if (0 == m_cRefs)
  219.   {
  220.     // We've reached a zero reference count for this COM object.
  221.     // So we tell the server housing to decrement its global object
  222.     // count so that the server will be unloaded if appropriate.
  223.     if (NULL != m_pServer)
  224.       m_pServer->ObjectsDown();
  225.     // We artificially bump the main ref count.  This fulfills one of
  226.     // the rules of aggregated objects and ensures that an indirect
  227.     // recursive call to this release won't occur because of other
  228.     // delegating releases that might happen in our own destructor.
  229.     m_cRefs++;
  230.     delete this;
  231.   }
  232.   return ulCount;
  233. }
  234. /*---------------------------------------------------------------------------
  235.   COLicCruiseCar's nested implementation of the ICruise interface including
  236.   Constructor, Destructor, QueryInterface, AddRef, Release,
  237.   Engage, and Adjust.
  238. ---------------------------------------------------------------------------*/
  239. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  240.   Method:   COLicCruiseCar::CImpICruise::CImpICruise
  241.   Summary:  Constructor for the CImpICruise interface instantiation.
  242.   Args:     COLicCruiseCar* pBackObj,
  243.               Back pointer to the parent outer object.
  244.             IUnknown* pUnkOuter)
  245.               Pointer to the outer Unknown.  For delegation.
  246.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter.
  247.   Returns:  void
  248. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  249. COLicCruiseCar::CImpICruise::CImpICruise(
  250.   COLicCruiseCar* pBackObj,
  251.   IUnknown* pUnkOuter)
  252. {
  253.   // Init the Interface Ref Count (used for debugging only).
  254.   m_cRefI = 0;
  255.   // Init the Back Object Pointer to point to the outer object.
  256.   m_pBackObj = pBackObj;
  257.   // Init the CImpICruise interface's delegating Unknown pointer.  We use
  258.   // the Back Object pointer for IUnknown delegation here if we are not
  259.   // being aggregated.  If we are being aggregated we use the supplied
  260.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  261.   // assignment requires no AddRef because the CImpICruise lifetime is
  262.   // quaranteed by the lifetime of the parent object in which
  263.   // CImpICruise is nested.
  264.   if (NULL == pUnkOuter)
  265.   {
  266.     m_pUnkOuter = pBackObj;
  267.     LOG("P: COLicCruiseCar::CImpICruise Constructor. Non-Aggregating.");
  268.   }
  269.   else
  270.   {
  271.     m_pUnkOuter = pUnkOuter;
  272.     LOG("P: COLicCruiseCar::CImpICruise Constructor. Aggregating.");
  273.   }
  274.   return;
  275. }
  276. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  277.   Method:   COLicCruiseCar::CImpICruise::~CImpICruise
  278.   Summary:  Destructor for the CImpICruise interface instantiation.
  279.   Args:     void
  280.   Modifies: .
  281.   Returns:  void
  282. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  283. COLicCruiseCar::CImpICruise::~CImpICruise(void)
  284. {
  285.   LOG("P: COLicCruiseCar::CImpICruise Destructor.");
  286.   return;
  287. }
  288. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  289.   Method:   COLicCruiseCar::CImpICruise::QueryInterface
  290.   Summary:  The QueryInterface IUnknown member of this ICruise interface
  291.             implementation that delegates to m_pUnkOuter, whatever it is.
  292.   Args:     REFIID riid,
  293.               [in] GUID of the Interface being requested.
  294.             PPVOID ppv)
  295.               [out] Address of the caller's pointer variable that will
  296.               receive the requested interface pointer.
  297.   Modifies: .
  298.   Returns:  HRESULT
  299.               Returned by the delegated outer QueryInterface call.
  300. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  301. STDMETHODIMP COLicCruiseCar::CImpICruise::QueryInterface(
  302.                REFIID riid,
  303.                PPVOID ppv)
  304. {
  305.   LOG("P: COLicCruiseCar::CImpICruise::QueryInterface. Delegating.");
  306.   // Delegate this call to the outer object's QueryInterface.
  307.   return m_pUnkOuter->QueryInterface(riid, ppv);
  308. }
  309. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  310.   Method:   COLicCruiseCar::CImpICruise::AddRef
  311.   Summary:  The AddRef IUnknown member of this ICruise interface
  312.             implementation that delegates to m_pUnkOuter, whatever it is.
  313.   Args:     void
  314.   Modifies: m_cRefI.
  315.   Returns:  ULONG
  316.               Returned by the delegated outer AddRef call.
  317. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  318. STDMETHODIMP_(ULONG) COLicCruiseCar::CImpICruise::AddRef(void)
  319. {
  320.   // Increment the Interface Reference Count.
  321.   ++m_cRefI;
  322.   LOGF1("P: COLicCruiseCar::CImpICruise::Addref. Delegating. New cI=%i.", m_cRefI);
  323.   // Delegate this call to the outer object's AddRef.
  324.   return m_pUnkOuter->AddRef();
  325. }
  326. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  327.   Method:   COLicCruiseCar::CImpICruise::Release
  328.   Summary:  The Release IUnknown member of this ICruise interface
  329.             implementation that delegates to m_pUnkOuter, whatever it is.
  330.   Args:     void
  331.   Modifies: .
  332.   Returns:  ULONG
  333.               Returned by the delegated outer Release call.
  334. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  335. STDMETHODIMP_(ULONG) COLicCruiseCar::CImpICruise::Release(void)
  336. {
  337.   // Decrement the Interface Reference Count.
  338.   --m_cRefI;
  339.   LOGF1("P: COLicCruiseCar::CImpICruise::Release. Delegating. New cI=%i.",m_cRefI);
  340.   // Delegate this call to the outer object's Release.
  341.   return m_pUnkOuter->Release();
  342. }
  343. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  344.   Method:   COLicCruiseCar::CImpICruise::Engage
  345.   Summary:  The Engage member method of this ICruise interface
  346.             implementation.  A simple empty method on a COLicCruiseCar COM
  347.             object for tutorial purposes.  Presumably if this Car object
  348.             were modeling a real Car then the Engage method would turn
  349.             the Cruise control system on or off.
  350.   Args:     BOOL bOnOff)
  351.               TRUE for On; FALSE for Off.
  352.   Modifies: .
  353.   Returns:  HRESULT
  354.               NOERROR
  355. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  356. STDMETHODIMP COLicCruiseCar::CImpICruise::Engage(
  357.                BOOL bOnOff)
  358. {
  359.   LOGF1("P: COLicCruiseCar::CImpICruise::Engage. Called. bOnOff=%i.",bOnOff);
  360.   return NOERROR;
  361. }
  362. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  363.   Method:   COLicCruiseCar::CImpICruise::Adjust
  364.   Summary:  The Adjust member method of this ICruise interface
  365.             implementation.  A simple empty method on a COLicCruiseCar COM
  366.             object for tutorial purposes.  Presumably if this Car object
  367.             were modeling a real Car then the Adjust method would allow
  368.             notching the cruise set speed up or down by increments of 3 mph.
  369.   Args:     BOOL bUpDown)
  370.               TRUE for Up; FALSE for Down.
  371.   Modifies: .
  372.   Returns:  HRESULT
  373.               NOERROR
  374. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  375. STDMETHODIMP COLicCruiseCar::CImpICruise::Adjust(
  376.                BOOL bUpDown)
  377. {
  378.   LOGF1("P: COLicCruiseCar::CImpICruise::Adjust. Called. bUpDown=%i.",bUpDown);
  379.   return NOERROR;
  380. }