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