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

Windows编程

开发平台:

Visual C++

  1. /*+==========================================================================
  2.   File:      UTILCAR.CPP
  3.   Summary:   Implementation file for the aggregatable COUtilityCar COM
  4.              object class.
  5.              UTILCAR showcases the construction of the COUtilityCar COM
  6.              object class with the IUnknown, ICar, and IUtility interfaces.
  7.              This is done through Containment reuse of COCar's ICar
  8.              interface features.
  9.              For a comprehensive tutorial code tour of this module's
  10.              contents and offerings see the accompanying COMOBJ.TXT
  11.              file.  For more specific technical details on the internal
  12.              workings see the comments dispersed throughout the
  13.              module's source code.
  14.   Classes:   COUtilityCar
  15.   Functions: none.
  16.   Origin:    10-3-97: atrent - Created. [Revised]
  17. ----------------------------------------------------------------------------
  18.   This file is part of the Microsoft COM Tutorial Code Samples.
  19.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  20.   This source code is intended only as a supplement to Microsoft
  21.   Development Tools and/or on-line documentation.  See these other
  22.   materials for detailed information regarding Microsoft code samples.
  23.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  24.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  25.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  26.   PARTICULAR PURPOSE.
  27. ==========================================================================+*/
  28. /*---------------------------------------------------------------------------
  29.   We include WINDOWS.H for all Win32 applications.
  30.   We include OLE2.H because we will make calls to the COM/OLE Libraries.
  31.   We include APPUTIL.H because we will be building this application using
  32.     the convenient Virtual Window and Dialog classes and other
  33.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  34.   We include ICARS.H and CARGUIDS.H for the common car-related Interface
  35.     class, GUID, and CLSID specifications.
  36.   We include COMOBJI.H because it has internal class declarations and
  37.     resource ID definitions specific for this DLL.
  38.   We include COMOBJ.H because it has the interface declarations.
  39.   We include CAR.H because it has the class COCar declarations.
  40.   We include UTILCAR.H because it has the class COUtilityCar declarations.
  41. ---------------------------------------------------------------------------*/
  42. #include <windows.h>
  43. #include <ole2.h>
  44. #include <apputil.h>
  45. #include <icars.h>
  46. #include <carguids.h>
  47. #include "comobji.h"
  48. #define _LOCALCALLS_
  49. #include "comobj.h"
  50. #include "car.h"
  51. #include "utilcar.h"
  52. /*---------------------------------------------------------------------------
  53.   COUtilityCar's implementation of its main COM object class including
  54.   Constructor, Destructor, QueryInterface, AddRef, and Release.
  55. ---------------------------------------------------------------------------*/
  56. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  57.   Method:   COUtilityCar::COUtilityCar
  58.   Summary:  COUtilityCar Constructor. Note the member initializers:
  59.             "m_ImpICar(this, pUnkOuter)" and "m_ImpIUtility(this,
  60.             pUnkOuter)" which are used to pass the 'this' and
  61.             pUnkOuter pointers of this constructor function to the
  62.             constructors that instantiate the implementations of
  63.             the CImpICar and CImpIUtility interfaces (which are both
  64.             nested inside this present COUtilityCar Object Class.
  65.   Args:     IUnknown* pUnkOuter)
  66.               Pointer to the the outer Unknown.  NULL means this COM Object
  67.               is not being Aggregated.  Non NULL means it is being created
  68.               on behalf of an outside COM object that is reusing it via
  69.               aggregation.
  70.   Modifies: m_cRefs, m_pUnkOuter.
  71.   Returns:  void
  72. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  73. COUtilityCar::COUtilityCar(
  74.   IUnknown* pUnkOuter) :
  75.   m_ImpICar(this, pUnkOuter),
  76.   m_ImpIUtility(this, pUnkOuter)
  77. {
  78.   // Zero the COM object's reference count.
  79.   m_cRefs = 0;
  80.   // No AddRef necessary if non-NULL, as we're nested.
  81.   m_pUnkOuter = pUnkOuter;
  82.   // Zero the pointer to the contained COCar object's ICar interface.
  83.   m_pICar = NULL;
  84.   LOGF1("D: COUtilityCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  85.   return;
  86. }
  87. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  88.   Method:   COUtilityCar::~COUtilityCar
  89.   Summary:  COUtilityCar Destructor.
  90.   Args:     void
  91.   Modifies: .
  92.   Returns:  void
  93. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  94. COUtilityCar::~COUtilityCar(void)
  95. {
  96.   LOG("D: COUtilityCar::Destructor.");
  97.   m_pICar->Release();
  98.   return;
  99. }
  100. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  101.   Method:   COUtilityCar::Init
  102.   Summary:  COUtilityCar Initialization method.
  103.   Args:     void
  104.   Modifies: m_pUnkCar, m_pICar, m_cRefs.
  105.   Returns:  HRESULT
  106.               Standard result code. NOERROR for success.
  107. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  108. HRESULT COUtilityCar::Init(void)
  109. {
  110.   HRESULT hr;
  111.   LOG("D: COUtilityCar::Init.");
  112.   // Create an instance of the COCar object and ask for its ICar
  113.   // interface directly.  We pass NULL for the pUnkOuter because we
  114.   // are not aggregating.  It is here that we are reusing the COCar
  115.   // COM Object through the Containment technique.  We cache the
  116.   // pointer to the ICar interface for later delegation use.  We
  117.   // don't need to AddRef it here because CreateCar does that for us.
  118.   hr = CreateCar(NULL, IID_ICar, (PPVOID) &m_pICar);
  119.   return (hr);
  120. }
  121. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  122.   Method:   COUtilityCar::QueryInterface
  123.   Summary:  QueryInterface of the COUtilityCar non-delegating
  124.             IUnknown implementation.
  125.   Args:     REFIID riid,
  126.               [in] GUID of the Interface being requested.
  127.             PPVOID ppv)
  128.               [out] Address of the caller's pointer variable that will
  129.               receive the requested interface pointer.
  130.   Modifies: .
  131.   Returns:  HRESULT
  132. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  133. STDMETHODIMP COUtilityCar::QueryInterface(
  134.                REFIID riid,
  135.                PPVOID ppv)
  136. {
  137.   HRESULT hr = E_NOINTERFACE;
  138.   *ppv = NULL;
  139.   if (IID_IUnknown == riid)
  140.   {
  141.     *ppv = this;
  142.     LOG("D: COUtilityCar::QueryInterface. 'this' pIUnknown returned");
  143.   }
  144.   else if (IID_ICar == riid)
  145.   {
  146.     *ppv = &m_ImpICar;
  147.     LOG("D: COUtilityCar::QueryInterface. pICar returned");
  148.   }
  149.   else if (IID_IUtility == riid)
  150.   {
  151.     *ppv = &m_ImpIUtility;
  152.     LOG("D: COUtilityCar::QueryInterface. pIUtility returned");
  153.   }
  154.   if (NULL != *ppv)
  155.   {
  156.     // We've handed out a pointer to the interface so obey the COM rules
  157.     //   and AddRef the reference count.
  158.     ((LPUNKNOWN)*ppv)->AddRef();
  159.     hr = NOERROR;
  160.   }
  161.   return (hr);
  162. }
  163. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  164.   Method:   COUtilityCar::AddRef
  165.   Summary:  AddRef of the COUtilityCar non-delegating IUnknown implementation.
  166.   Args:     void
  167.   Modifies: m_cRefs.
  168.   Returns:  ULONG
  169.               New value of m_cRefs (COM object's reference count).
  170. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  171. STDMETHODIMP_(ULONG) COUtilityCar::AddRef(void)
  172. {
  173.   m_cRefs++;
  174.   LOGF1("D: COUtilityCar::AddRef. New cRefs=%i.", m_cRefs);
  175.   return m_cRefs;
  176. }
  177. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  178.   Method:   COUtilityCar::Release
  179.   Summary:  Release of the COUtilityCar non-delegating IUnknown implementation.
  180.   Args:     void
  181.   Modifies: m_cRefs.
  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) COUtilityCar::Release(void)
  186. {
  187.   m_cRefs--;
  188.   LOGF1("D: COUtilityCar::Release. New cRefs=%i.", m_cRefs);
  189.   if (0 == m_cRefs)
  190.   {
  191.     // We artificially bump the main ref count to prevent reentrancy
  192.     // via the main object destructor.
  193.     m_cRefs++;
  194.     delete this;
  195.   }
  196.   return m_cRefs;;
  197. }
  198. /*---------------------------------------------------------------------------
  199.   COUtilityCar's nested implementation of the ICar interface including
  200.   Constructor, Destructor, QueryInterface, AddRef, Release,
  201.   Shift, Clutch, Speed, and Steer.
  202. ---------------------------------------------------------------------------*/
  203. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  204.   Method:   COUtilityCar::CImpICar::CImpICar
  205.   Summary:  Constructor for the CImpICar interface instantiation.
  206.   Args:     COUtilityCar* pBackObj,
  207.               Back pointer to the parent outer object.
  208.             IUnknown* pUnkOuter)
  209.               Pointer to the outer Unknown.  For delegation.
  210.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter.
  211.   Returns:  void
  212. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  213. COUtilityCar::CImpICar::CImpICar(
  214.   COUtilityCar* pBackObj,
  215.   IUnknown* pUnkOuter)
  216. {
  217.   // Init the Interface Ref Count (used for debugging only).
  218.   m_cRefI=0;
  219.   // Init the Back Object Pointer to point to the outer object.
  220.   m_pBackObj=pBackObj;
  221.   // Init the CImpICar interface's delegating Unknown pointer.  We use
  222.   // the Back Object pointer for IUnknown delegation here if we are not
  223.   // 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 CImpICar lifetime is
  226.   // quaranteed by the lifetime of the parent object in which
  227.   // CImpICar is nested.
  228.   if (NULL == pUnkOuter)
  229.   {
  230.     m_pUnkOuter = pBackObj;
  231.     LOG("D: COUtilityCar::CImpICar Constructor. Non-Aggregating");
  232.   }
  233.   else
  234.   {
  235.     m_pUnkOuter = pUnkOuter;
  236.     LOG("D: COUtilityCar::CImpICar Constructor. Aggregating");
  237.   }
  238.   return;
  239. }
  240. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  241.   Method:   COUtilityCar::CImpICar::~CImpICar
  242.   Summary:  Destructor for the CImpICar interface instantiation.
  243.   Args:     void
  244.   Modifies: .
  245.   Returns:  void
  246. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  247. COUtilityCar::CImpICar::~CImpICar(void)
  248. {
  249.   LOG("D: COUtilityCar::CImpICar Destructor.");
  250.   return;
  251. }
  252. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  253.   Method:   COUtilityCar::CImpICar::QueryInterface
  254.   Summary:  The QueryInterface IUnknown member of this ICar interface
  255.             implementation that delegates to m_pUnkOuter, whatever it is.
  256.   Args:     REFIID riid,
  257.               [in] GUID of the Interface being requested.
  258.             PPVOID ppv)
  259.               [out] Address of the caller's pointer variable that will
  260.               receive the requested interface pointer.
  261.   Modifies: .
  262.   Returns:  HRESULT
  263.               Returned by the delegated outer QueryInterface call.
  264. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  265. STDMETHODIMP COUtilityCar::CImpICar::QueryInterface(
  266.                REFIID riid,
  267.                PPVOID ppv)
  268. {
  269.   LOG("D: COUtilityCar::CImpICar::QueryInterface. Delegating.");
  270.   // Delegate this call to the outer object's QueryInterface.
  271.   return m_pUnkOuter->QueryInterface(riid, ppv);
  272. }
  273. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  274.   Method:   COUtilityCar::CImpICar::AddRef
  275.   Summary:  The AddRef IUnknown member of this ICar interface
  276.             implementation that delegates to m_pUnkOuter, whatever it is.
  277.   Args:     void
  278.   Modifies: m_cRefI.
  279.   Returns:  ULONG
  280.               Returned by the delegated outer AddRef call.
  281. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  282. STDMETHODIMP_(ULONG) COUtilityCar::CImpICar::AddRef(void)
  283. {
  284.   // Increment the Interface Reference Count.
  285.   ++m_cRefI;
  286.   LOGF1("D: COUtilityCar::CImpICar::Addref. Delegating. New cI=%i.", m_cRefI);
  287.   // Delegate this call to the outer object's AddRef.
  288.   return m_pUnkOuter->AddRef();
  289. }
  290. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  291.   Method:   COUtilityCar::CImpICar::Release
  292.   Summary:  The Release IUnknown member of this ICar interface
  293.             implementation that delegates to m_pUnkOuter, whatever it is.
  294.   Args:     void
  295.   Modifies: .
  296.   Returns:  ULONG
  297.               Returned by the delegated outer Release call.
  298. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  299. STDMETHODIMP_(ULONG) COUtilityCar::CImpICar::Release(void)
  300. {
  301.   // Decrement the Interface Reference Count.
  302.   --m_cRefI;
  303.   LOGF1("D: COUtilityCar::CImpICar::Release. Delegating. New cI=%i.", m_cRefI);
  304.   // Delegate this call to the outer object's Release.
  305.   return m_pUnkOuter->Release();
  306. }
  307. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  308.   Method:   COUtilityCar::CImpICar::Shift
  309.   Summary:  The Shift member method of this ICar interface implementation.
  310.             A simple empty method on a COUtilityCar COM object for tutorial
  311.             purposes.  Presumably if this Car object were modeling
  312.             a real Car then the Shift method would shift to the specified
  313.             gear.
  314.   Args:     short nGear
  315.               0 - Neutral; 1 - 5 First 5 forward gears; 6 - Reverse.
  316.   Modifies: .
  317.   Returns:  HRESULT
  318.               NOERROR
  319. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  320. STDMETHODIMP COUtilityCar::CImpICar::Shift(
  321.                short nGear)
  322. {
  323.   LOGF1("D: COUtilityCar::CImpICar::Shift. Delegating. nGear=%i.",nGear);
  324.   m_pBackObj->m_pICar->Shift(nGear);
  325.   return NOERROR;
  326. }
  327. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  328.   Method:   COUtilityCar::CImpICar::Clutch
  329.   Summary:  The Clutch member method of this ICar interface implementation.
  330.             A simple empty method on a COUtilityCar COM object for tutorial
  331.             purposes.  Presumably if this Car object were modeling
  332.             a real Car then the Clutch method would engage the clutch the
  333.             specified amount.
  334.   Args:     short nEngaged)
  335.               Percent clutch is engaged (0 to 100%).
  336.   Modifies: .
  337.   Returns:  HRESULT
  338.               NOERROR
  339. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  340. STDMETHODIMP COUtilityCar::CImpICar::Clutch(
  341.                short nEngaged)
  342. {
  343.   LOGF1("D: COUtilityCar::CImpICar::Clutch. Delegating. nEngaged=%i.",nEngaged);
  344.   m_pBackObj->m_pICar->Clutch(nEngaged);
  345.   return NOERROR;
  346. }
  347. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  348.   Method:   COUtilityCar::CImpICar::Speed
  349.   Summary:  The Propel member method of this ICar interface implementation.
  350.             A simple empty method on a COUtilityCar COM object for tutorial
  351.             purposes.  Presumably if this Car object were modeling
  352.             a real Car then this method would accelerate/brake to bring
  353.             the car to the specified speed.
  354.   Args:     short nMph
  355.               New speed in miles per hour.
  356.   Modifies: .
  357.   Returns:  HRESULT
  358.               NOERROR
  359. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  360. STDMETHODIMP COUtilityCar::CImpICar::Speed(
  361.                short nMph)
  362. {
  363.   LOGF1("D: COUtilityCar::CImpICar::Speed. Delegating. nMph=%i.",nMph);
  364.   m_pBackObj->m_pICar->Speed(nMph);
  365.   return NOERROR;
  366. }
  367. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  368.   Method:   COUtilityCar::CImpICar::Steer
  369.   Summary:  The Steer member method of this ICar interface implementation.
  370.             A simple empty method on a COUtilityCar COM object for tutorial
  371.             purposes.  Presumably if this Car object were modeling
  372.             a real Car then the Steer method would set the steering
  373.             angle of the Car.
  374.   Args:     short nAngle)
  375.               0 degrees straight ahead, -45 Full left, +45 Full right.
  376.   Modifies: .
  377.   Returns:  HRESULT
  378.               NOERROR
  379. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  380. STDMETHODIMP COUtilityCar::CImpICar::Steer(
  381.                short nAngle)
  382. {
  383.  LOGF1("D: COUtilityCar::CImpICar::Steer. Delegating. nAngle=%i.",nAngle);
  384.   m_pBackObj->m_pICar->Steer(nAngle);
  385.   return NOERROR;
  386. }
  387. /*---------------------------------------------------------------------------
  388.   COUtilityCar's nested implementation of the IUtility interface including
  389.   Constructor, Destructor, QueryInterface, AddRef, Release,
  390.   Offroad, and Winch.
  391. ---------------------------------------------------------------------------*/
  392. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  393.   Method:   COUtilityCar::CImpIUtility::CImpIUtility
  394.   Summary:  Constructor for the CImpIUtility interface instantiation.
  395.   Args:     COUtilityCar* pBackObj,
  396.               Back pointer to the parent outer object.
  397.             IUnknown* pUnkOuter)
  398.               Pointer to the outer Unknown.  For delegation.
  399.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter.
  400.   Returns:  void
  401. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  402. COUtilityCar::CImpIUtility::CImpIUtility(
  403.   COUtilityCar* pBackObj,
  404.   IUnknown* pUnkOuter)
  405. {
  406.   // Init the Interface Ref Count (used for debugging only).
  407.   m_cRefI = 0;
  408.   // Init the Back Object Pointer to point to the outer object.
  409.   m_pBackObj = pBackObj;
  410.   // Init the CImpIUtility interface's delegating Unknown pointer.  We use
  411.   // the Back Object pointer for IUnknown delegation here if we are not
  412.   // being aggregated.  If we are being aggregated we use the supplied
  413.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  414.   // assignment requires no AddRef because the CImpIUtility lifetime is
  415.   // quaranteed by the lifetime of the parent object in which
  416.   // CImpIUtility is nested.
  417.   if (NULL == pUnkOuter)
  418.   {
  419.     m_pUnkOuter = pBackObj;
  420.     LOG("D: COUtilityCar::CImpIUtility Constructor. Non-Aggregating.");
  421.   }
  422.   else
  423.   {
  424.     m_pUnkOuter = pUnkOuter;
  425.     LOG("D: COUtilityCar::CImpIUtility Constructor. Aggregating.");
  426.   }
  427.   return;
  428. }
  429. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  430.   Method:   COUtilityCar::CImpIUtility::~CImpIUtility
  431.   Summary:  Destructor for the CImpIUtility interface instantiation.
  432.   Args:     void
  433.   Modifies: .
  434.   Returns:  void
  435. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  436. COUtilityCar::CImpIUtility::~CImpIUtility(void)
  437. {
  438.   LOG("D: COUtilityCar::CImpIUtility Destructor.");
  439.   return;
  440. }
  441. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  442.   Method:   COUtilityCar::CImpIUtility::QueryInterface
  443.   Summary:  The QueryInterface IUnknown member of this IUtility interface
  444.             implementation that delegates to m_pUnkOuter, whatever it is.
  445.   Args:     REFIID riid,
  446.               [in] GUID of the Interface being requested.
  447.             PPVOID ppv)
  448.               [out] Address of the caller's pointer variable that will
  449.               receive the requested interface pointer.
  450.   Modifies: .
  451.   Returns:  HRESULT
  452.               Returned by the delegated outer QueryInterface call.
  453. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  454. STDMETHODIMP COUtilityCar::CImpIUtility::QueryInterface(
  455.                REFIID riid,
  456.                PPVOID ppv)
  457. {
  458.   LOG("D: COUtilityCar::CImpIUtility::QueryInterface. Delegating.");
  459.   // Delegate this call to the outer object's QueryInterface.
  460.   return m_pUnkOuter->QueryInterface(riid, ppv);
  461. }
  462. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  463.   Method:   COUtilityCar::CImpIUtility::AddRef
  464.   Summary:  The AddRef IUnknown member of this IUtility interface
  465.             implementation that delegates to m_pUnkOuter, whatever it is.
  466.   Args:     void
  467.   Modifies: m_cRefI.
  468.   Returns:  ULONG
  469.               Returned by the delegated outer AddRef call.
  470. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  471. STDMETHODIMP_(ULONG) COUtilityCar::CImpIUtility::AddRef(void)
  472. {
  473.   // Increment the Interface Reference Count.
  474.   ++m_cRefI;
  475.   LOGF1("D: COUtilityCar::CImpIUtility::Addref. Delegating. New cI=%i.", m_cRefI);
  476.   // Delegate this call to the outer object's AddRef.
  477.   return m_pUnkOuter->AddRef();
  478. }
  479. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  480.   Method:   COUtilityCar::CImpIUtility::Release
  481.   Summary:  The Release IUnknown member of this IUtility interface
  482.             implementation that delegates to m_pUnkOuter, whatever it is.
  483.   Args:     void
  484.   Modifies: .
  485.   Returns:  ULONG
  486.               Returned by the delegated outer Release call.
  487. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  488. STDMETHODIMP_(ULONG) COUtilityCar::CImpIUtility::Release(void)
  489. {
  490.   // Decrement the Interface Reference Count.
  491.   --m_cRefI;
  492.   LOGF1("D: COUtilityCar::CImpIUtility::Release. Delegating. New cI=%i.", m_cRefI);
  493.   // Delegate this call to the outer object's Release.
  494.   return m_pUnkOuter->Release();
  495. }
  496. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  497.   Method:   COUtilityCar::CImpIUtility::Offroad
  498.   Summary:  The Offroad member method of this IUtility interface
  499.             implementation.  A simple empty method on a COUtilityCar
  500.             COM object for tutorial purposes.  Presumably if this
  501.             UtilityCar object were modeling a real Car then the Offroad
  502.             method would function the 4-wheel drive transfer case and
  503.             shift it to the specified 4-wheel drive mode.
  504.   Args:     short nGear
  505.               0 = 2H or regular 2-wheel drive;
  506.               1 = 4H or 4-wheel drive high speed;
  507.               2 = neutral; and
  508.               3 = 4L or 4-wheel drive low speed).
  509.   Modifies: .
  510.   Returns:  HRESULT
  511.               NOERROR
  512. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  513. STDMETHODIMP COUtilityCar::CImpIUtility::Offroad(
  514.                short nGear)
  515. {
  516.   LOGF1("D: COUtilityCar::CImpIUtility::Offroad. Called. nGear=%i.",nGear);
  517.   return NOERROR;
  518. }
  519. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  520.   Method:   COUtilityCar::CImpIUtility::Winch
  521.   Summary:  The Winch member method of this IUtility interface
  522.             implementation.  A simple empty method on a COUtilityCar COM
  523.             object for tutorial purposes.  Presumably if this UtilityCar
  524.             object were modeling a real Car then the Winch method would
  525.             turn on/off the front-mounted Winch to the specified RPMs.
  526.   Args:     short nRpm
  527.               0 = off; 1 - 50 RPM.
  528.   Modifies: .
  529.   Returns:  HRESULT
  530.               NOERROR
  531. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  532. STDMETHODIMP COUtilityCar::CImpIUtility::Winch(
  533.                short nRpm)
  534. {
  535.   LOGF1("D: COUtilityCar::CImpIUtility::Winch. Called. nRpm=%i.",nRpm);
  536.   return NOERROR;
  537. }