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

Windows编程

开发平台:

Visual C++

  1. /*+==========================================================================
  2.   File:      SINK.CPP
  3.   Summary:   Implementation file for the COBallSink COM Object Class.
  4.              COBallSink offers a main IUnknown interface and the IBallSink
  5.              interface (with the Moving Ball related event features).
  6.              This multiple interface COM Object Class is achieved via the
  7.              technique of nested classes.  The implementation of the
  8.              IBallSink interface is nested inside the COBallSink Class.
  9.              For a comprehensive tutorial code tour of this module's
  10.              contents and offerings see the tutorial CONCLIEN.HTM
  11.              file. For more specific technical details on the internal
  12.              workings see the comments dispersed throughout the module's
  13.              source code.
  14.   Classes:   COBallSink.
  15.   Functions: none.
  16.   Origin:    6-3-96: atrent - Editor-inheritance from BALL.CPP in
  17.              the CONSERVE 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 OLECTL.H because it has definitions for connectable objects.
  33.   We include APPUTIL.H because we will be building this application using
  34.     the convenient Virtual Window and Dialog classes and other
  35.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  36.   We include IBALL.H and BALLGUID.H for the common Ball-related Interface
  37.     class, GUID, and CLSID specifications.
  38.   We include GUIBALL.H because it declares the class for the main C++
  39.     object that can service the Sink events.
  40.   We include SINK.H because it has the class COBallSink declarations.
  41. ---------------------------------------------------------------------------*/
  42. #include <windows.h>
  43. #include <ole2.h>
  44. #include <olectl.h>
  45. #include <apputil.h>
  46. #include <iball.h>
  47. #include <ballguid.h>
  48. #include "guiball.h"
  49. #include "sink.h"
  50. /*---------------------------------------------------------------------------
  51.   COBallSink's implementation of its main COM object class including
  52.   Constructor, Destructor, QueryInterface, AddRef, and Release.
  53. ---------------------------------------------------------------------------*/
  54. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  55.   Method:   COBallSink::COBallSink
  56.   Summary:  COBallSink Constructor. Note the member initializer:
  57.             "m_ImpIBallSink(this, pUnkOuter)" which is used to pass the
  58.             'this' and pUnkOuter pointers of this constructor function to
  59.             the constructor in the instantiation of the implementation of
  60.             the CImpIBallSink interface (which is nested inside this
  61.             present COBallSink Object Class).
  62.   Args:     IUnknown* pUnkOuter,
  63.               Pointer to the the outer Unknown.  NULL means this COM Object
  64.               is not being Aggregated.  Non NULL means it is being created
  65.               on behalf of an outside COM object that is reusing it via
  66.               aggregation.
  67.             CGuiBall* pGuiBall)
  68.               Pointer to the main C++ object that can service the BallSink
  69.               events.
  70.   Modifies: m_cRefs, m_pUnkOuter, m_pGuiBall.
  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. COBallSink::COBallSink(
  74.   IUnknown* pUnkOuter,
  75.   CGuiBall* pGuiBall) :
  76.   m_ImpIBallSink(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.   // Assign the pointer to the Sink service C++ object.
  83.   m_pGuiBall = pGuiBall;
  84.   return;
  85. }
  86. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  87.   Method:   COBallSink::~COBallSink
  88.   Summary:  COBallSink Destructor.
  89.   Args:     void
  90.   Modifies: .
  91.   Returns:  void
  92. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  93. COBallSink::~COBallSink(void)
  94. {
  95.   return;
  96. }
  97. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  98.   Method:   COBallSink::QueryInterface
  99.   Summary:  QueryInterface of the COBallSink non-delegating
  100.             IUnknown implementation.
  101.   Args:     REFIID riid,
  102.               [in] GUID of the Interface being requested.
  103.             PPVOID ppv)
  104.               [out] Address of the caller's pointer variable that will
  105.               receive the requested interface pointer.
  106.   Modifies: .
  107.   Returns:  HRESULT
  108. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  109. STDMETHODIMP COBallSink::QueryInterface(
  110.                REFIID riid,
  111.                PPVOID ppv)
  112. {
  113.   HRESULT hr = E_NOINTERFACE;
  114.   *ppv = NULL;
  115.   if (IID_IUnknown == riid)
  116.     *ppv = this;
  117.   else if (IID_IBallSink == riid)
  118.     *ppv = &m_ImpIBallSink;
  119.   if (NULL != *ppv)
  120.   {
  121.     // We've handed out a pointer to the interface so obey the COM rules
  122.     // and AddRef the reference count.
  123.     ((LPUNKNOWN)*ppv)->AddRef();
  124.     hr = NOERROR;
  125.   }
  126.   return (hr);
  127. }
  128. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  129.   Method:   COBallSink::AddRef
  130.   Summary:  AddRef of the COBallSink non-delegating IUnknown implementation.
  131.   Args:     void
  132.   Modifies: m_cRefs.
  133.   Returns:  ULONG
  134.               New value of m_cRefs (COM object's reference count).
  135. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  136. STDMETHODIMP_(ULONG) COBallSink::AddRef(void)
  137. {
  138.   ULONG cRefs;
  139.   cRefs = ++m_cRefs;
  140.   return cRefs;
  141. }
  142. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  143.   Method:   COBallSink::Release
  144.   Summary:  Release of the COBallSink non-delegating IUnknown implementation.
  145.   Args:     void
  146.   Modifies: m_cRefs.
  147.   Returns:  ULONG
  148.               New value of m_cRefs (COM object's reference count).
  149. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  150. STDMETHODIMP_(ULONG) COBallSink::Release(void)
  151. {
  152.   ULONG cRefs;
  153.   cRefs = --m_cRefs;
  154.   if (0 == cRefs)
  155.   {
  156.     // We artificially bump the main ref count to prevent reentrancy
  157.     // via the main object destructor.  Not really needed in this
  158.     // COBallSink but a good practice because we are aggregatable and
  159.     // may at some point in the future add something entertaining like
  160.     // some Releases to the COBallSink destructor.
  161.     m_cRefs++;
  162.     delete this;
  163.   }
  164.   return cRefs;
  165. }
  166. /*---------------------------------------------------------------------------
  167.   COBallSink's nested implementation of the IBallSink interface including
  168.   Constructor, Destructor, QueryInterface, AddRef, Release, Reset, Move,
  169.   and GetBall. This interface implementation also has internal methods
  170.   that are not particulary intended for outside clients: GetDimensions,
  171.   SetDimensions, GetDirection, SetDirection, GetPosition, SetPostion,
  172.   CheckBounce, and FindThread. The IBallSink interface only provides client
  173.   access to the IUnknown methods and the Reset, Move, and GetBall methods.
  174.   Some or all of these internal methods could be exposed by the IBallSink
  175.   interface by adding them to the IBallSink declaration in IBALL.H.
  176. ---------------------------------------------------------------------------*/
  177. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  178.   Method:   COBallSink::CImpIBallSink::CImpIBallSink
  179.   Summary:  Constructor for the CImpIBallSink interface instantiation.
  180.   Args:     COBallSink* pBackObj,
  181.               Back pointer to the parent outer object.
  182.             IUnknown* pUnkOuter
  183.               Pointer to the outer Unknown.  For delegation.
  184.   Modifies: m_pBackObj, m_pUnkOuter.
  185.   Returns:  void
  186. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  187. COBallSink::CImpIBallSink::CImpIBallSink(
  188.   COBallSink* pBackObj,
  189.   IUnknown* pUnkOuter)
  190. {
  191.   // Init the Back Object Pointer to point to the parent object.
  192.   m_pBackObj = pBackObj;
  193.   // Init the CImpIBallSink interface's delegating Unknown pointer.  We
  194.   // use the Back Object pointer for IUnknown delegation here if we are
  195.   // not being aggregated.  If we are being aggregated we use the supplied
  196.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  197.   // assignment requires no AddRef because the CImpIBallSink lifetime is
  198.   // quaranteed by the lifetime of the parent object in which
  199.   // CImpIBallSink is nested.
  200.   if (NULL == pUnkOuter)
  201.     m_pUnkOuter = pBackObj;
  202.   else
  203.     m_pUnkOuter = pUnkOuter;
  204.   return;
  205. }
  206. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  207.   Method:   COBallSink::CImpIBallSink::~CImpIBallSink
  208.   Summary:  Destructor for the CImpIBallSink interface instantiation.
  209.   Args:     void
  210.   Modifies: .
  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. COBallSink::CImpIBallSink::~CImpIBallSink(void)
  214. {
  215.   return;
  216. }
  217. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  218.   Method:   COBallSink::CImpIBallSink::QueryInterface
  219.   Summary:  The QueryInterface IUnknown member of this IBallSink interface
  220.             implementation that delegates to m_pUnkOuter, whatever it is.
  221.   Args:     REFIID riid,
  222.               [in] GUID of the Interface being requested.
  223.             PPVOID ppv)
  224.               [out] Address of the caller's pointer variable that will
  225.               receive the requested interface pointer.
  226.   Modifies: .
  227.   Returns:  HRESULT
  228.               Returned by the delegated outer QueryInterface call.
  229. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  230. STDMETHODIMP COBallSink::CImpIBallSink::QueryInterface(
  231.                REFIID riid,
  232.                PPVOID ppv)
  233. {
  234.   // Delegate this call to the outer object's QueryInterface.
  235.   return m_pUnkOuter->QueryInterface(riid, ppv);
  236. }
  237. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  238.   Method:   COBallSink::CImpIBallSink::AddRef
  239.   Summary:  The AddRef IUnknown member of this IBallSink interface
  240.             implementation that delegates to m_pUnkOuter, whatever it is.
  241.   Args:     void
  242.   Modifies: .
  243.   Returns:  ULONG
  244.               Returned by the delegated outer AddRef call.
  245. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  246. STDMETHODIMP_(ULONG) COBallSink::CImpIBallSink::AddRef(void)
  247. {
  248.   // Delegate this call to the outer object's AddRef.
  249.   return m_pUnkOuter->AddRef();
  250. }
  251. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  252.   Method:   COBallSink::CImpIBallSink::Release
  253.   Summary:  The Release IUnknown member of this IBallSink interface
  254.             implementation that delegates to m_pUnkOuter, whatever it is.
  255.   Args:     void
  256.   Modifies: .
  257.   Returns:  ULONG
  258.               Returned by the delegated outer Release call.
  259. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  260. STDMETHODIMP_(ULONG) COBallSink::CImpIBallSink::Release(void)
  261. {
  262.   // Delegate this call to the outer object's Release.
  263.   return m_pUnkOuter->Release();
  264. }
  265. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  266.   Method:   COBallSink::CImpIBallSink::BounceBottom
  267.   Summary:  Perform actions appropriate for when the ball bounces against
  268.             the bottom boundary. For example, ask GUI to make a sound.
  269.   Args:     void
  270.   Modifies: ...
  271.   Returns:  void
  272. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  273. STDMETHODIMP COBallSink::CImpIBallSink::BounceBottom(
  274.                void)
  275. {
  276.   HRESULT hr = NOERROR;
  277.   // Ask the GUI Ball to issue an appropriate sound indicating the ball
  278.   // bouncing off the Bottom boundary.
  279.   m_pBackObj->m_pGuiBall->BounceBottom();
  280.   return hr;
  281. }
  282. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  283.   Method:   COBallSink::CImpIBallSink::BounceLeft
  284.   Summary:  Perform actions appropriate for when the ball bounces against
  285.             the Left boundary. For example, ask GUI to make a sound.
  286.   Args:     void
  287.   Modifies: ...
  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. STDMETHODIMP COBallSink::CImpIBallSink::BounceLeft(
  291.                void)
  292. {
  293.   HRESULT hr = NOERROR;
  294.   // Ask the GUI Ball to issue an appropriate sound indicating the ball
  295.   // bouncing off the Side boundary.
  296.   m_pBackObj->m_pGuiBall->BounceSide();
  297.   return hr;
  298. }
  299. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  300.   Method:   COBallSink::CImpIBallSink::BounceRight
  301.   Summary:  Perform actions appropriate for when the ball bounces against
  302.             the right boundary. For example, ask GUI to make a sound.
  303.   Args:     void
  304.   Modifies: ...
  305.   Returns:  void
  306. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  307. STDMETHODIMP COBallSink::CImpIBallSink::BounceRight(
  308.                void)
  309. {
  310.   HRESULT hr = NOERROR;
  311.   // Ask the GUI Ball to issue an appropriate sound indicating the ball
  312.   // bouncing off the Side boundary.
  313.   m_pBackObj->m_pGuiBall->BounceSide();
  314.   return hr;
  315. }
  316. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  317.   Method:   COBallSink::CImpIBallSink::BounceTop
  318.   Summary:  Perform actions appropriate for when the ball bounces against
  319.             the Top boundary. For example, ask GUI to make a sound.
  320.   Args:     void
  321.   Modifies: ...
  322.   Returns:  void
  323. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  324. STDMETHODIMP COBallSink::CImpIBallSink::BounceTop(
  325.                void)
  326. {
  327.   HRESULT hr = NOERROR;
  328.   // Ask the GUI Ball to issue an appropriate sound indicating the ball
  329.   // bouncing off the Top boundary.
  330.   m_pBackObj->m_pGuiBall->BounceTop();
  331.   return hr;
  332. }