⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ball.cpp

📁 服务器方面的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*+==========================================================================
  File:      BALL.CPP

  Summary:   Implementation file for the COBall COM Object Class (for
             aggregatable COBall COM Objects). This module provides a free
             threaded virtual ball object. The ball has internal
             algorithms that determine its position within a bounded two
             dimensional area. No display or other GUI behavior is done in
             this ball.  It is a mathematical entity. Clients of this ball
             can command it to reset, move, and reveal its current
             position, size, and color. These last are used by a client
             that displays images of this ball. The color in particular is
             an internal property maintained by the ball that indicates
             the thread of execution that last moved this ball.

             COBall offers a main standard IUnknown interface (basic COM
             object features) and the custom IBall interface (Moving Ball
             related features).  This multiple interface COM Object Class
             is achieved via the technique of nested classes.  The
             implementation of the IBall interface is nested inside the
             COBall Class.

             This file also implements some internal C++ classes (CXForm
             and CBallThread) that provide internal support for the custom
             IBall interface.

             For a comprehensive tutorial code tour of this module's
             contents and offerings see the accompanying FRESERVE.TXT
             file. For more specific technical details on the internal
             workings see the comments dispersed throughout the module's
             source code.

  Classes:   CXForm, CBallThread, COBall.

  Functions: none.

  Origin:    4-5-96: atrent - Editor-inheritance from CAR.CPP in
             the DLLSERVE OLE Tutorial Code Sample. Also borrows from
             the GDIDEMO sample in the Win32 samples of the Win32 SDK.

----------------------------------------------------------------------------
  This file is part of the Microsoft OLE Tutorial Code Samples.

  Copyright (C) Microsoft Corporation, 1996.  All rights reserved.

  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  See these other
  materials for detailed information regarding Microsoft code samples.

  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
==========================================================================+*/


/*---------------------------------------------------------------------------
  We include WINDOWS.H for all Win32 applications.
  We include OLE2.H because we will be making calls to the OLE Libraries.
  We include APPUTIL.H because we will be building this application using
    the convenient Virtual Window and Dialog classes and other
    utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  We include IBALL.H and BALLGUID.H for the common Ball-related Interface
    class, GUID, and CLSID specifications.
  We include SERVER.H because it has internal class declarations and
    resource ID definitions specific for this DLL.
  We include BALL.H because it has the class COBall declarations.
---------------------------------------------------------------------------*/
#include "preserve.h"
#include "ball.h"


/*---------------------------------------------------------------------------
  COBall's implementation of its internal utility class CXForm.
---------------------------------------------------------------------------*/


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   CXForm::Clear

  Summary:  Clears and initializes the transformation matrix.

  Args:     void

  Modifies: ...

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void CXForm::Clear(void)
{
  int Row,Col;

  for(Row=0; Row < 3; Row++)
    for(Col=0; Col < 3; Col++)
      if(Row == Col)
        XForm[Row][Col] = 1;
      else
        XForm[Row][Col] = 0;

  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   CXForm::Scale

  Summary:  Method to allow setting the transformation to multiply
            by a scale factor.

  Args:     int xScale
              x Scale factor.
            int yScale
              y Scale factor.

  Modifies: ...

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void CXForm::Scale(int xScale, int yScale)
{
  int idx;

  for(idx=0; idx < 3; idx++)
  {
    XForm[idx][0] = XForm[idx][0] * xScale;
    XForm[idx][1] = XForm[idx][1] * yScale;
  }

  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   CXForm::Trans

  Summary:  Perform the transform uing the internal matrix.

  Args:     int xTrans
              x coordinate.
            int yTrans
              y coordinate.

  Modifies: ...

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void CXForm::Trans(int xTrans, int yTrans)
{
  XForm[2][0] = XForm[2][0] + xTrans;
  XForm[2][1] = XForm[2][1] + yTrans;

  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   CXForm::Point

  Summary:  Transform a point.

  Args:     POINT* pPoint
              Pointer to the point.

  Modifies: ...

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void CXForm::Point(POINT* pPoint)
{
  int x,y;

  x = (XForm[0][0] * pPoint->x) + (XForm[1][0] * pPoint->y) + XForm[2][0];
  y = (XForm[0][1] * pPoint->x) + (XForm[1][1] * pPoint->y) + XForm[2][1];

  pPoint->x = x;
  pPoint->y = y;

  return;
}


/*---------------------------------------------------------------------------
  COBall's implementation of its main COM object class including
  Constructor, Destructor, QueryInterface, AddRef, and Release.
---------------------------------------------------------------------------*/

/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::COBall

  Summary:  COBall Constructor. Note the member initializer:
            "m_ImpIBall(this, pUnkOuter)" which is used to pass the 'this'
            and pUnkOuter pointers of this constructor function to the
            constructor in the instantiation of the implementation of the
            CImpIBall interface (which is nested inside this present
            COBall Object Class).

  Args:     IUnknown* pUnkOuter,
              Pointer to the the outer Unknown.  NULL means this COM Object
              is not being Aggregated.  Non NULL means it is being created
              on behalf of an outside COM object that is reusing it via
              aggregation.
            CServer* pServer)
              Pointer to the server's control object.

  Modifies: m_cRefs, m_pUnkOuter, m_pServer.

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
COBall::COBall(
  IUnknown* pUnkOuter,
  CServer* pServer) :
  m_ImpIBall(this, pUnkOuter)
{
  // Zero the COM object's reference count.
  m_cRefs = 0;

  // No AddRef necessary if non-NULL, as we're nested.
  m_pUnkOuter = pUnkOuter;

  // Assign the pointer to the server control object.
  m_pServer = pServer;

  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::~COBall

  Summary:  COBall Destructor.

  Args:     void

  Modifies: .

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
COBall::~COBall(void)
{
  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::QueryInterface

  Summary:  QueryInterface of the COBall non-delegating
            IUnknown implementation.

  Args:     REFIID riid,
              [in] GUID of the Interface being requested.
            PPVOID ppv)
              [out] Address of the caller's pointer variable that will
              receive the requested interface pointer.

  Modifies: .

  Returns:  HRESULT
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP COBall::QueryInterface(
               REFIID riid,
               PPVOID ppv)
{
  HRESULT hr = E_NOINTERFACE;

  if (OwnThis())
  {
    *ppv = NULL;

    if (IID_IUnknown == riid)
      *ppv = this;
    else if (IID_IBall == riid)
      *ppv = &m_ImpIBall;

    if (NULL != *ppv)
    {
      // We've handed out a pointer to the interface so obey the COM rules
      // and AddRef the reference count.
      ((LPUNKNOWN)*ppv)->AddRef();
      hr = NOERROR;
    }

    UnOwnThis();
  }

  return (hr);
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::AddRef

  Summary:  AddRef of the COBall non-delegating IUnknown implementation.

  Args:     void

  Modifies: m_cRefs.

  Returns:  ULONG
              New value of m_cRefs (COM object's reference count).
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP_(ULONG) COBall::AddRef(void)
{
  ULONG cRefs;

  if (OwnThis())
  {
    cRefs = ++m_cRefs;

    UnOwnThis();
  }

  return cRefs;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::Release

  Summary:  Release of the COBall non-delegating IUnknown implementation.

  Args:     void

  Modifies: m_cRefs.

  Returns:  ULONG
              New value of m_cRefs (COM object's reference count).
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP_(ULONG) COBall::Release(void)
{
  ULONG cRefs;

  if (OwnThis())
  {
    cRefs = --m_cRefs;

    if (0 == cRefs)
    {
      // We've reached a zero reference count for this COM object.
      // So we tell the server housing to decrement its global object
      // count so that the server will be unloaded if appropriate.
      if (NULL != m_pServer)
        m_pServer->ObjectsDown();

      // We artificially bump the main ref count to prevent reentrancy
      // via the main object destructor.  Not really needed in this
      // COBall but a good practice because we are aggregatable and
      // may at some point in the future add something entertaining like
      // some Releases to the COBall destructor. We relinquish thread
      // ownership of this object before deleting it--a good practice.
      m_cRefs++;
      UnOwnThis();
      delete this;
    }
    else
      UnOwnThis();
  }

  return cRefs;
}


/*---------------------------------------------------------------------------
  COBall's nested implementation of the IBall interface including
  Constructor, Destructor, QueryInterface, AddRef, Release, Reset, Move,
  and GetBall. This interface implementation also has internal methods
  that are not particulary intended for outside clients: GetDimensions,
  SetDimensions, GetDirection, SetDirection, GetPosition, SetPostion,
  CheckBounce, and FindThread. The IBall interface only provides client
  access to the IUnknown methods and the Reset, Move, and GetBall methods.
---------------------------------------------------------------------------*/

/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::CImpIBall::CImpIBall

  Summary:  Constructor for the CImpIBall interface instantiation.

  Args:     COBall* pBackObj,
              Back pointer to the parent outer object.
            IUnknown* pUnkOuter
              Pointer to the outer Unknown.  For delegation.

  Modifies: m_pBackObj, m_pUnkOuter.

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
COBall::CImpIBall::CImpIBall(
  COBall* pBackObj,
  IUnknown* pUnkOuter)
{
  size_t i;
  BYTE r=128, g=128, b=128;

  // Init the Back Object Pointer to point to the parent object.
  m_pBackObj = pBackObj;

  // Init the CImpIBall interface's delegating Unknown pointer.  We use
  // the Back Object pointer for IUnknown delegation here if we are not
  // being aggregated.  If we are being aggregated we use the supplied
  // pUnkOuter for IUnknown delegation.  In either case the pointer
  // assignment requires no AddRef because the CImpIBall lifetime is
  // quaranteed by the lifetime of the parent object in which
  // CImpIBall is nested.
  if (NULL == pUnkOuter)
    m_pUnkOuter = pBackObj;
  else
    m_pUnkOuter = pUnkOuter;

  // Now initialize the Ball application entity data.
  m_bAlive       = TRUE;
  m_xDirection   = 0;
  m_yDirection   = 0;
  m_bNewPosition = FALSE;
  m_xPosition    = 0;
  m_yPosition    = 0;
  m_nWidth       = 30;
  m_nHeight      = 30;
  m_xSkew        = BALL_MOVE_SKEW;
  m_ySkew        = BALL_MOVE_SKEW;
  m_crColor      = RGB(0,0,0);

  // Clear point transformation array.
  m_XForm.Clear();

  // Init BallThread array--init colors and clear thread Ids.
  // The BallThreads are the threads that contend to move and/or
  // paint the ball object.
  for (i = 0; i < MAX_BALLTHREADS; i++)
    m_aBallThreads[i].Id = 0;
  m_aBallThreads[0].Color = RGB(0  ,  0,255);  // Blue
  m_aBallThreads[1].Color = RGB(255,  0,  0);  // Red
  m_aBallThreads[2].Color = RGB(0  ,255,  0);  // Green
  m_aBallThreads[3].Color = RGB(0  ,  0,  0);  // Black
  m_aBallThreads[4].Color = RGB(255,  0,255);  // Purple
  m_aBallThreads[5].Color = RGB(0  ,255,255);  // Aqua
  m_aBallThreads[6].Color = RGB(255,255,  0);  // Brown
  if (MAX_BALLTHREADS > 8)
    for (i=7; i<MAX_BALLTHREADS; i++)
    {
      // Fill the remainder with some random colors.
      m_aBallThreads[i].Color = RGB(r,g,b);
      r = (BYTE) lRandom() % 255;
      g = (BYTE) lRandom() % 255;
      b = (BYTE) lRandom() % 255;
    }

  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::CImpIBall::~CImpIBall

  Summary:  Destructor for the CImpIBall interface instantiation.

  Args:     void

  Modifies: .

  Returns:  void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
COBall::CImpIBall::~CImpIBall(void)
{
  return;
}


/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  Method:   COBall::CImpIBall::GetDimensions

  Summary:  Internal utility method to get the ball x,y dimensions.

  Args:     POINT* pDimension
              Pointer to the point that will contain the dimensions.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -