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

Windows编程

开发平台:

Visual C++

  1. /*+==========================================================================
  2.   File:      CAR.CPP
  3.   Summary:   Implementation file for the COCar COM Object Class (for
  4.              aggregatable Car COM Objects).
  5.              COCar offers a main IUnknown interface and the ICar
  6.              interface (Car-related features).  This multiple interface
  7.              COM Object Class is achieved via the technique of nested
  8.              classes--the implementation of the ICar interface is
  9.              nested inside of the COCar Class.
  10.              For a comprehensive tutorial code tour of this module's
  11.              contents and offerings see the tutorial APTSERVE.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:   COCar.
  15.   Functions: none.
  16.   Origin:    3-20-96: atrent - Editor-inheritance from CAR.CPP in
  17.                the LOCSERVE 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 make calls to 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 MICARS.H and CARGUIDS.H for the common car-related Interface
  36.     class, GUID, and CLSID specifications.
  37.   We include SERVER.H because it has internal class declarations and
  38.     resource ID definitions specific for this executable.
  39.   We include CAR.H because it has the class COCar declarations.
  40. ---------------------------------------------------------------------------*/
  41. #include <windows.h>
  42. #include <ole2.h>
  43. #include <apputil.h>
  44. #include <micars.h>
  45. #include <carguids.h>
  46. #include "server.h"
  47. #include "car.h"
  48. /*---------------------------------------------------------------------------
  49.   COCar'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:   COCar::COCar
  54.   Summary:  COCar Constructor. Note the member initializer:
  55.             "m_ImpICar(this, pUnkOuter)" which is used to pass the 'this'
  56.             and pUnkOuter pointers of this constructor function to the
  57.             constructor in the instantiation of the implementation of
  58.             the CImpICar interface (which is nested inside this present
  59.             COCar 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, m_pServer.
  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. COCar::COCar(
  71.   IUnknown* pUnkOuter,
  72.   CServer* pServer) :
  73.   m_ImpICar(this, pUnkOuter)
  74. {
  75.   // Zero the COM object's reference count.
  76.   m_cRefs = 0;
  77.   // No AddRef necessary if non-NULL, as we're nested.
  78.   m_pUnkOuter = pUnkOuter;
  79.   // Assign the pointer to the server control object.
  80.   m_pServer = pServer;
  81.   LOGF2("L<%X>: COCar Constructor. m_pUnkOuter=0x%X.",TID,m_pUnkOuter);
  82.   return;
  83. }
  84. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  85.   Method:   COCar::~COCar
  86.   Summary:  COCar Destructor.
  87.   Args:     void
  88.   Modifies: .
  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(void)
  92. {
  93.   LOGF1("L<%X>: COCar::Destructor.",TID);
  94.   return;
  95. }
  96. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  97.   Method:   COCar::QueryInterface
  98.   Summary:  QueryInterface of the COCar non-delegating
  99.             IUnknown implementation.
  100.   Args:     REFIID riid,
  101.               [in] GUID of the Interface being requested.
  102.             PPVOID ppv)
  103.               [out] Address of the caller's pointer variable that will
  104.               receive the requested interface pointer.
  105.   Modifies: *ppv.
  106.   Returns:  HRESULT
  107. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  108. STDMETHODIMP COCar::QueryInterface(
  109.                REFIID riid,
  110.                PPVOID ppv)
  111. {
  112.   HRESULT hr = E_NOINTERFACE;
  113.   *ppv = NULL;
  114.   if (IID_IUnknown == riid)
  115.   {
  116.     *ppv = this;
  117.     LOGF1("L<%X>: COCar::QueryInterface. 'this' pIUnknown returned.",TID);
  118.   }
  119.   else if (IID_ICar == riid)
  120.   {
  121.     *ppv = &m_ImpICar;
  122.     LOGF1("L<%X>: COCar::QueryInterface. pICar returned.",TID);
  123.   }
  124.   if (NULL != *ppv)
  125.   {
  126.     // We've handed out a pointer to the interface so obey the COM rules
  127.     // and AddRef the reference count.
  128.     ((LPUNKNOWN)*ppv)->AddRef();
  129.     hr = NOERROR;
  130.   }
  131.   return (hr);
  132. }
  133. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  134.   Method:   COCar::AddRef
  135.   Summary:  AddRef of the COCar non-delegating IUnknown implementation.
  136.   Args:     void
  137.   Modifies: m_cRefs.
  138.   Returns:  ULONG
  139.               New value of m_cRefs (COM object's reference count).
  140. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  141. STDMETHODIMP_(ULONG) COCar::AddRef(void)
  142. {
  143.   m_cRefs++;
  144.   LOGF2("L<%X>: COCar::AddRef. New cRefs=%i.",TID,m_cRefs);
  145.   return m_cRefs;
  146. }
  147. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  148.   Method:   COCar::Release
  149.   Summary:  Release of the COCar non-delegating IUnknown implementation.
  150.   Args:     void
  151.   Modifies: m_cRefs.
  152.   Returns:  ULONG
  153.               New value of m_cRefs (COM object's reference count).
  154. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  155. STDMETHODIMP_(ULONG) COCar::Release(void)
  156. {
  157.   m_cRefs--;
  158.   LOGF2("L<%X>: COCar::Release. New cRefs=%i.",TID,m_cRefs);
  159.   if (0 == m_cRefs)
  160.   {
  161.     // We artificially bump the main ref count to prevent reentrancy
  162.     // via the main object destructor.  Not really needed in this
  163.     // COCar but a good practice because we are aggregatable and
  164.     // may at some point in the future add something entertaining like
  165.     // some Releases in the COCar destructor.
  166.     m_cRefs++;
  167.     delete this;
  168.     // We've reached a zero reference count for this COM object.
  169.     // So we tell the server housing to decrement its global object
  170.     // count so that the server will be unloaded if appropriate.
  171.     if (NULL != m_pServer)
  172.       m_pServer->ObjectsDown();
  173.   }
  174.   return m_cRefs;
  175. }
  176. /*---------------------------------------------------------------------------
  177.   COCar's nested implementation of the ICar interface including
  178.   Constructor, Destructor, QueryInterface, AddRef, Release,
  179.   Shift, Clutch, Speed, and Steer.
  180. ---------------------------------------------------------------------------*/
  181. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  182.   Method:   COCar::CImpICar::CImpICar
  183.   Summary:  Constructor for the CImpICar interface instantiation.
  184.   Args:     COCar* pBackObj,
  185.               Back pointer to the parent outer object.
  186.             IUnknown* pUnkOuter
  187.               Pointer to the outer Unknown.  For delegation.
  188.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter.
  189.   Returns:  void
  190. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  191. COCar::CImpICar::CImpICar(
  192.   COCar* pBackObj,
  193.   IUnknown* pUnkOuter)
  194. {
  195.   // Zero an ICar method call counter (used for tutorial purposes only).
  196.   m_C = 0;
  197.   // Init the Interface Ref Count (used for debugging only).
  198.   m_cRefI = 0;
  199.   // Init the Back Object Pointer to point to the parent object.
  200.   m_pBackObj = pBackObj;
  201.   // Init the CImpICar interface's delegating Unknown pointer.  We use
  202.   // the Back Object pointer for IUnknown delegation here if we are not
  203.   // being aggregated.  If we are being aggregated we use the supplied
  204.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  205.   // assignment requires no AddRef because the CImpICar lifetime is
  206.   // guaranteed by the lifetime of the parent object in which
  207.   // CImpICar is nested.
  208.   if (NULL == pUnkOuter)
  209.   {
  210.     m_pUnkOuter = pBackObj;
  211.     LOGF1("L<%X>: COCar::CImpICar Constructor. Non-Aggregating.",TID);
  212.   }
  213.   else
  214.   {
  215.     m_pUnkOuter = pUnkOuter;
  216.     LOGF1("L<%X>: COCar::CImpICar Constructor. Aggregating.",TID);
  217.   }
  218.   return;
  219. }
  220. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  221.   Method:   COCar::CImpICar::~CImpICar
  222.   Summary:  Destructor for the CImpICar interface instantiation.
  223.   Args:     void
  224.   Modifies: .
  225.   Returns:  void
  226. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  227. COCar::CImpICar::~CImpICar(void)
  228. {
  229.   LOGF1("L<%X>: COCar::CImpICar Destructor.",TID);
  230.   return;
  231. }
  232. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  233.   Method:   COCar::CImpICar::QueryInterface
  234.   Summary:  The QueryInterface IUnknown member of this ICar interface
  235.             implementation that delegates to m_pUnkOuter, whatever it is.
  236.   Args:     REFIID riid,
  237.               [in] GUID of the Interface being requested.
  238.             PPVOID ppv)
  239.               [out] Address of the caller's pointer variable that will
  240.               receive the requested interface pointer.
  241.   Modifies: .
  242.   Returns:  HRESULT
  243.               Returned by the delegated outer QueryInterface call.
  244. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  245. STDMETHODIMP COCar::CImpICar::QueryInterface(
  246.                REFIID riid,
  247.                PPVOID ppv)
  248. {
  249.   LOGF1("L<%X>: COCar::CImpICar::QueryInterface. Delegating.",TID);
  250.   // Delegate this call to the outer object's QueryInterface.
  251.   return m_pUnkOuter->QueryInterface(riid, ppv);
  252. }
  253. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  254.   Method:   COCar::CImpICar::AddRef
  255.   Summary:  The AddRef IUnknown member of this ICar interface
  256.             implementation that delegates to m_pUnkOuter, whatever it is.
  257.   Args:     void
  258.   Modifies: m_cRefI.
  259.   Returns:  ULONG
  260.               Returned by the delegated outer AddRef call.
  261. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  262. STDMETHODIMP_(ULONG) COCar::CImpICar::AddRef(void)
  263. {
  264.   // Increment the Interface Reference Count.
  265.   ++m_cRefI;
  266.   LOGF2("L<%X>: COCar::CImpICar::Addref. Delegating. New cI=%i.",TID,m_cRefI);
  267.   // Delegate this call to the outer object's AddRef.
  268.   return m_pUnkOuter->AddRef();
  269. }
  270. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  271.   Method:   COCar::CImpICar::Release
  272.   Summary:  The Release IUnknown member of this ICar interface
  273.             implementation that delegates to m_pUnkOuter, whatever it is.
  274.   Args:     void
  275.   Modifies: m_cRefI.
  276.   Returns:  ULONG
  277.               Returned by the delegated outer Release call.
  278. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  279. STDMETHODIMP_(ULONG) COCar::CImpICar::Release(void)
  280. {
  281.   // Decrement the Interface Reference Count.
  282.   --m_cRefI;
  283.   LOGF2("L<%X>: COCar::CImpICar::Release. Delegating. New cI=%i.",TID,m_cRefI);
  284.   // Delegate this call to the outer object's Release.
  285.   return m_pUnkOuter->Release();
  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::Shift
  289.   Summary:  The Shift member method of this ICar interface implementation.
  290.             A simple empty method on a COCar COM object for tutorial
  291.             purposes.  Presumably if this Car object were modeling
  292.             a real Car then the Shift method would shift to the specified
  293.             gear.
  294.   Args:     short nGear
  295.               0 - Neutral; 1 - 5 First 5 forward gears; 6 - Reverse.
  296.   Modifies: m_C.
  297.   Returns:  HRESULT
  298.               NOERROR
  299. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  300. STDMETHODIMP COCar::CImpICar::Shift(
  301.                short nGear)
  302. {
  303.   // Increment method call counter purely for tutorial reasons.
  304.   m_C++;
  305.   LOGF2("L<%X>: COCar::CImpICar::Shift. Called. ICar calls=%i.",TID,m_C);
  306.   return NOERROR;
  307. }
  308. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  309.   Method:   COCar::CImpICar::Clutch
  310.   Summary:  The Clutch member method of this ICar interface implementation.
  311.             A simple empty method on a COCar COM object for tutorial
  312.             purposes.  Presumably if this Car object were modeling
  313.             a real Car then the Clutch method would engage the clutch the
  314.             specified amount.
  315.   Args:     short nEngaged)
  316.               Percent clutch is engaged (0 to 100%).
  317.   Modifies: m_C.
  318.   Returns:  HRESULT
  319.               NOERROR
  320. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  321. STDMETHODIMP COCar::CImpICar::Clutch(
  322.                short nEngaged)
  323. {
  324.   // Increment method call counter purely for tutorial reasons.
  325.   m_C++;
  326.   LOGF2("L<%X>: COCar::CImpICar::Clutch. Called. ICar calls=%i.",TID,m_C);
  327.   return NOERROR;
  328. }
  329. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  330.   Method:   COCar::CImpICar::Speed
  331.   Summary:  The Speed member method of this ICar interface implementation.
  332.             A simple empty method on a COCar COM object for tutorial
  333.             purposes.  Presumably if this Car object were modeling
  334.             a real Car then this method would accelerate/brake to bring
  335.             the car to the specified speed.
  336.   Args:     short nMph
  337.               New speed in miles per hour.
  338.   Modifies: m_C.
  339.   Returns:  HRESULT
  340.               NOERROR
  341. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  342. STDMETHODIMP COCar::CImpICar::Speed(
  343.                short nMph)
  344. {
  345.   // Increment method call counter purely for tutorial reasons.
  346.   m_C++;
  347.   LOGF2("L<%X>: COCar::CImpICar::Speed. Called. ICar calls=%i.",TID,m_C);
  348.   return NOERROR;
  349. }
  350. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  351.   Method:   COCar::CImpICar::Steer
  352.   Summary:  The Steer member method of this ICar interface implementation.
  353.             A simple empty method on a COCar COM object for tutorial
  354.             purposes.  Presumably if this Car object were modeling
  355.             a real Car then the Steer method would set the steering
  356.             angle of the Car.
  357.   Args:     short nAngle)
  358.               0 degrees straight ahead, -45 Full left, +45 Full right.
  359.   Modifies: m_C.
  360.   Returns:  HRESULT
  361.               NOERROR
  362. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  363. STDMETHODIMP COCar::CImpICar::Steer(
  364.                short nAngle)
  365. {
  366.   // Increment method call counter purely for tutorial reasons.
  367.   m_C++;
  368.   LOGF2("L<%X>: COCar::CImpICar::Steer. Called. ICar calls=%i.",TID,m_C);
  369.   return NOERROR;
  370. }