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 / comobj / car.cpp next >
C/C++ Source or Header  |  1997-08-05  |  15KB  |  478 lines

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