📄 ball.cpp
字号:
Modifies: *pDimension.
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::GetDimensions(POINT* pDimension)
{
pDimension->x = m_nWidth;
pDimension->y = m_nHeight;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::SetDimensions
Summary: Internal utility method to set the ball x,y dimensions.
Args: int nWidth
New Ball width.
int nHeight
New Ball Height.
Modifies: .
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::SetDimensions(int nWidth, int nHeight)
{
m_nWidth = nWidth;
m_nHeight = nHeight;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::GetDirection
Summary: Internal utility method to get the ball direction.
Args: POINT* pDirection
Pointer to the Point that will contain the x,y direction
data.
Modifies: ...
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::GetDirection(POINT* pDirection)
{
pDirection->x = m_xDirection;
pDirection->y = m_yDirection;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::SetDirection
Summary: Internal utility method to set the ball direction.
Args: int xDirection
x coordinate of the new direction.
int yDirection
y coordinate of the new direction.
Modifies: ...
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::SetDirection(int xDirection, int yDirection)
{
m_xDirection = xDirection;
m_yDirection = yDirection;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::GetPosition
Summary: Internal utility method to get current the ball position.
Args: POINT* pPosition
Pointer to the Point that is the position.
Modifies: *pPostion.
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::GetPosition(POINT* pPosition)
{
POINT Org;
Org.x = 0;
Org.y = 0;
m_XForm.Point(&Org);
pPosition->x = Org.x;
pPosition->y = Org.y;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::SetPosition
Summary: Internal utility method to set current the ball position.
Args: int x
x-coordinate of new position.
int y
y-coordinate of new position.
Modifies: ...
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
void COBall::CImpIBall::SetPosition(int x, int y)
{
m_bNewPosition = TRUE;
m_xPosition = x;
m_yPosition = y;
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::CheckBounce
Summary: Internal utility method to check the current ball position,
dimension, and direction data and determine if the ball has
hit the internal WinRect bounding rectangle. If it has then
the ball data is recalculated to achieve a "bounce" effect
for the ball as it moves.
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 COBall::CImpIBall::CheckBounce(void)
{
POINT Pos, Dir, Dim;
int xNewPos, yNewPos, xNewDir, yNewDir;
GetPosition(&Pos);
GetDirection(&Dir);
GetDimensions(&Dim);
// Check each edge of the client rectangle. If the ball goes past the
// boundries, reset its position and direction to give it a "bounce"
// effect the next time it is displayed.
xNewDir = Dir.x;
yNewDir = Dir.y;
xNewPos = Pos.x + Dir.x;
yNewPos = Pos.y + Dir.y;
if(xNewPos < m_WinRect.left)
{
xNewDir = ((lRandom() % m_xSkew) + m_xSkew);
SetPosition(m_WinRect.left, Pos.y);
}
if((xNewPos + Dim.x) > m_WinRect.right)
{
xNewDir = -(((int)lRandom() % m_xSkew) + m_xSkew);
SetPosition(m_WinRect.right - Dim.x, Pos.y);
}
if(yNewPos < m_WinRect.top)
{
yNewDir = ((lRandom() % m_ySkew) + m_ySkew);
SetPosition(Pos.x, m_WinRect.top);
}
if((yNewPos + Dim.y) > m_WinRect.bottom)
{
yNewDir = -(((int)lRandom() % m_ySkew) + m_ySkew);
SetPosition(Pos.x, m_WinRect.bottom - Dim.y);
}
SetDirection(xNewDir, yNewDir);
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::FindThread
Summary: Internal utility method to Find the thread that is now
executing this code. If the executing thread is not already in
the Thread array remember the new Thread's Id and add it to the
array. This in effect assigns the thread a color that can be
used for tutorial display of which thread is executing on the
ball object.
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 COBall::CImpIBall::FindThread(void)
{
BOOL bFound = FALSE;
DWORD dwTId = GetCurrentThreadId();
size_t i = 0;
while(!bFound && i<MAX_BALLTHREADS)
{
if (m_aBallThreads[i].Id == 0)
{
// Found empty slot. This simple array logic allows no empty holes.
m_aBallThreads[i].Id = dwTId;
bFound = TRUE;
}
else
{
if (m_aBallThreads[i].Id == dwTId)
{
// Found previous visiting thread--use its assigned color.
m_crColor = m_aBallThreads[i].Color;
bFound = TRUE;
}
else
{
i++;
if (i >= MAX_BALLTHREADS)
{
// Thread array is full--use a gray color for all other
// excess visiting threads.
m_crColor = RGB(127,127,127);
bFound = TRUE;
}
}
}
}
return;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::QueryInterface
Summary: The QueryInterface IUnknown member of this IBall interface
implementation that delegates to m_pUnkOuter, whatever it is.
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
Returned by the delegated outer QueryInterface call.
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP COBall::CImpIBall::QueryInterface(
REFIID riid,
PPVOID ppv)
{
// Delegate this call to the outer object's QueryInterface.
return m_pUnkOuter->QueryInterface(riid, ppv);
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::AddRef
Summary: The AddRef IUnknown member of this IBall interface
implementation that delegates to m_pUnkOuter, whatever it is.
Args: void
Modifies: .
Returns: ULONG
Returned by the delegated outer AddRef call.
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP_(ULONG) COBall::CImpIBall::AddRef(void)
{
// Delegate this call to the outer object's AddRef.
return m_pUnkOuter->AddRef();
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::Release
Summary: The Release IUnknown member of this IBall interface
implementation that delegates to m_pUnkOuter, whatever it is.
Args: void
Modifies: .
Returns: ULONG
Returned by the delegated outer Release call.
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP_(ULONG) COBall::CImpIBall::Release(void)
{
// Delegate this call to the outer object's Release.
return m_pUnkOuter->Release();
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::Reset
Summary: The Reset member method of the IBall interface implementation.
Called by outside clients of a COBall object to reset the
virtual ball. It is restored to the upper left corner.
Args: RECT* pNewRect,
Pointer to a RECT structure. Tells the COBall the bounding
rectangle within which the ball can move.
short nBallSize,
The size of the ball in pixels. nBallSize == Width == Height
meaning that a circle is assumed.
Modifies: ...
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP COBall::CImpIBall::Reset(
RECT* pNewRect,
short nBallSize)
{
HRESULT hr = E_FAIL;
int nDim, xDirection, yDirection;
if (OwnThis())
{
// Find the thread who is executing this and remember its color.
FindThread();
m_xSkew = m_ySkew = BALL_MOVE_SKEW;
m_WinRect.left = pNewRect->left;
m_WinRect.top = pNewRect->top;
m_WinRect.right = pNewRect->right;
m_WinRect.bottom = pNewRect->bottom;
nDim = nBallSize ? nBallSize : max(5, m_WinRect.right / 13);
SetDimensions(nDim, nDim);
SetPosition(0, 0);
xDirection = ((lRandom() % m_xSkew) + m_xSkew);
yDirection = ((lRandom() % m_ySkew) + m_ySkew);
SetDirection(xDirection, yDirection);
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::CImpIBall::Move
Summary: The Move member method of this IBall interface implementation.
Called by outside clients of a COBall object to advance the
"motion" of this COBall virtual ball entity.
Args: BOOL bAlive
TRUE means stay alive; FALSE means don't move but die.
Modifies: m_bAlive.
Returns: BOOL
TRUE means the move was done and the ball is still alive.
FALSE means the move was not done and the ball has been
killed.
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP COBall::CImpIBall::Move(BOOL bAlive, BOOL* bRet)
{
*bRet = FALSE;
if (OwnThis())
{
if (bAlive)
{
// Find thread that is now executing this code. Remember its Id and
// assign it a color. If this thread previously visited here then
// use its remembered values. In any case, set a color value in
// m_crColor of its existing or newly assigned color.
FindThread();
// Ask the Ball if it has hit any of the edges of the current window
// rectangle. If so, it will recalculate its position and direction to
// achieve a "bounce" effect in its motion the next time it is painted.
CheckBounce();
// Calculate and set new ball position.
if(m_bNewPosition)
{
m_bNewPosition = FALSE;
m_XForm.Clear();
m_XForm.Trans(m_xPosition, m_yPosition);
}
else
m_XForm.Trans(m_xDirection, m_yDirection);
}
else
m_bAlive = FALSE;
*bRet = m_bAlive;
UnOwnThis();
}
return S_OK;
}
/*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
Method: COBall::CImpIBall::GetBall
Summary: The GetBall member method of this IBall interface
implementation. Called by outside clients of a COBall object
to get the necessary data on the moving ball to enable GUI
display of an actual image of this virtual ball. This COBall
is a data entity only that is kept alive by client threads
that call Move. A GUI client can independently call GetBall
to allow it to display some visual representation of the Ball.
Args: POINT* pOrg,
Pointer to a point that will contain the current origin
position of the ball.
POINT* pExt,
Pointer to a point that will contain the current extent
size of the ball.
COLORREF* pcrColor)
Pointer to a COLORREF that will contain the current color
of the ball. This color is determined by the last thread
that was executing in the ball before this call is made.
Modifies: ...
Returns: void
M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
STDMETHODIMP COBall::CImpIBall::get_Ball(
POINT* pOrg,
POINT* pExt,
COLORREF* pcrColor)
{
HRESULT hr = E_FAIL;
if (OwnThis())
{
*pcrColor = m_crColor;
pOrg->x = 0;
pOrg->y = 0;
m_XForm.Point(pOrg);
pExt->x = m_nWidth;
pExt->y = m_nHeight;
m_XForm.Point(pExt);
hr = NOERROR;
UnOwnThis();
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -