📄 robot1.cpp
字号:
#define INITGUID
#include <math.h>
#include "Robot1.h"
#include "Utility.h"
IMPLEMENT_DYNCREATE(ComRobot, CCmdTarget)
IMPLEMENT_OLECREATE(ComRobot, "Robot",
0xc8bd7017, 0x34fd, 0x11d0, 0x8b, 0xb9, 0xed, 0xea, 0x36, 0xf8, 0xb3, 0xc);
BEGIN_INTERFACE_MAP(ComRobot, CCmdTarget)
INTERFACE_PART(ComRobot, IID_IRobot, RobotInner)
INTERFACE_PART(ComRobot, IID_ISimpleDrawable, DrawInner)
END_INTERFACE_MAP()
// Useful constants
const ULONG BufferZoneRadius = 40;
const ULONG TriangleHeight = 7;
const ULONG TriangleHalfWidth = 7;
const ULONG RobotHeight = 65;
const ULONG RobotWidth = 55;
//
// Constructor and destructor
//
ComRobot::ComRobot()
: m_usCurrHeading(0UL),
m_ulCurrXPos(0UL),
m_ulCurrYPos(0UL)
{
VerboseMsg("In ComRobot constructor.\n");
// Allow other components to aggregate us if they need to
EnableAggregation();
AfxOleLockApp();
}
ComRobot::~ComRobot()
{
VerboseMsg("In ComRobot destructor.\n");
AfxOleUnlockApp();
}
//
// Nested Robot IUnknown members
//
STDMETHODIMP_(ULONG)
ComRobot::XRobotInner::AddRef()
{
METHOD_PROLOGUE(ComRobot, RobotInner)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG)
ComRobot::XRobotInner::Release()
{
METHOD_PROLOGUE(ComRobot, RobotInner)
return pThis->ExternalRelease();
}
STDMETHODIMP
ComRobot::XRobotInner::QueryInterface(REFIID riid, PPVOID ppv)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
return pThis->ExternalQueryInterface(&riid, ppv);
}
//
// IRobot interface members for nested Robot class
//
STDMETHODIMP
ComRobot::XRobotInner::Initialize(ULONG ulXPos,
ULONG ulYPos)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In XRobotInner::Initialize.\n");
// Set our starting position
pThis->m_ulCurrXPos = ulXPos;
pThis->m_ulCurrYPos = ulYPos;
return NOERROR;
}
STDMETHODIMP
ComRobot::XRobotInner::TurnTo(USHORT usDegrees)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In TurnTo.\n");
// Set the new heading, taking care to ensure that the value
// lies between 0 and 360 (higher values will wrap around)
pThis->m_usCurrHeading = usDegrees % 360;
return NOERROR;
}
STDMETHODIMP
ComRobot::XRobotInner::GetCurrentHeading(PUSHORT pusDegrees)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In GetCurrentHeading.\n");
*pusDegrees = pThis->m_usCurrHeading;
return NOERROR;
}
STDMETHODIMP
ComRobot::XRobotInner::GetCurrentPosition(PULONG pulXPos, PULONG pulYPos)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In GetCurrentPosition.\n");
*pulXPos = pThis->m_ulCurrXPos;
*pulYPos = pThis->m_ulCurrYPos;
return NOERROR;
}
STDMETHODIMP
ComRobot::XRobotInner::MoveForward(ULONG ulNumUnits)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In MoveForward.\n");
pThis->m_ulCurrXPos += (LONG)(ulNumUnits *
cos(Radians(pThis->m_usCurrHeading)));
pThis->m_ulCurrYPos -= (LONG)(ulNumUnits *
sin(Radians(pThis->m_usCurrHeading)));
return NOERROR;
}
STDMETHODIMP
ComRobot::XRobotInner::MoveBackward(ULONG ulNumUnits)
{
METHOD_PROLOGUE(ComRobot, RobotInner)
VerboseMsg("In MoveBackward.\n");
pThis->m_ulCurrXPos += (LONG)(ulNumUnits *
cos(Radians(pThis->m_usCurrHeading + 180)));
pThis->m_ulCurrYPos -= (LONG)(ulNumUnits *
sin(Radians(pThis->m_usCurrHeading + 180)));
return NOERROR;
}
//
// Nested Draw IUnknown members
//
STDMETHODIMP_(ULONG)
ComRobot::XDrawInner::AddRef()
{
METHOD_PROLOGUE(ComRobot, DrawInner)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG)
ComRobot::XDrawInner::Release()
{
METHOD_PROLOGUE(ComRobot, DrawInner)
return pThis->ExternalRelease();
}
STDMETHODIMP
ComRobot::XDrawInner::QueryInterface(REFIID riid, PPVOID ppv)
{
METHOD_PROLOGUE(ComRobot, DrawInner)
return pThis->ExternalQueryInterface(&riid, ppv);
}
//
// ISimpleDrawable interface members for nested Draw class
//
STDMETHODIMP
ComRobot::XDrawInner::Draw(HDC hDC)
{
HRESULT hResult;
CDC DC;
METHOD_PROLOGUE(ComRobot, DrawInner)
VerboseMsg("In XDrawInner::Draw.\n");
hResult = DC.Attach(hDC);
if (FAILED(hResult)) {
VerboseMsg("Failed to attach hDC to CDC object in XDrawInner::Draw.\n");
return hResult;
}
// Draw the heading tick
pThis->DrawHeading(DC);
CDC memorydc;
CBitmap m_bmRobotBitmap;
m_bmRobotBitmap.LoadBitmap("Robot");
memorydc.CreateCompatibleDC(&DC);
CBitmap* pOldBitmap = memorydc.SelectObject (&m_bmRobotBitmap);
hResult = DC.BitBlt(pThis->m_ulCurrXPos - (RobotWidth / 2),
pThis->m_ulCurrYPos - (RobotHeight / 2),
RobotWidth,
RobotHeight,
&memorydc,
0,
0,
SRCCOPY);
memorydc.SelectObject (pOldBitmap);
if (FAILED(hResult)) {
VerboseMsg("Failed to draw Robot rectangle.\n");
return hResult;
}
return NOERROR;
}
VOID ComRobot::DrawHeading(CDC& DC)
{
// Our heading indicator should be filled in blue
CBrush TriangleFillBrush(Blue);
CBrush *pOldBrush = DC.SelectObject(&TriangleFillBrush);
// Calculate some trig stuff and hold onto it for later
DOUBLE dCosHeading = cos(Radians(m_usCurrHeading));
DOUBLE dSinHeading = sin(Radians(m_usCurrHeading));
// Top of triangle
ULONG ulTopX = m_ulCurrXPos + (BufferZoneRadius * dCosHeading) +
(TriangleHeight * dCosHeading);
ULONG ulTopY = m_ulCurrYPos - (BufferZoneRadius * dSinHeading) -
(TriangleHeight * dSinHeading);
// Right vertice
ULONG ulRightVerticeX = m_ulCurrXPos + (BufferZoneRadius * dCosHeading) +
(TriangleHalfWidth * dSinHeading);
ULONG ulRightVerticeY = m_ulCurrYPos - (BufferZoneRadius * dSinHeading) +
(TriangleHalfWidth * dCosHeading);
// Left vertice
ULONG ulLeftVerticeX = m_ulCurrXPos + (BufferZoneRadius * dCosHeading) -
(TriangleHalfWidth * dSinHeading);
ULONG ulLeftVerticeY = m_ulCurrYPos - (BufferZoneRadius * dSinHeading) -
(TriangleHalfWidth * dCosHeading);
// Create the polygon array
POINT aPoints[] = { { ulTopX, ulTopY, },
{ ulLeftVerticeX, ulLeftVerticeY, },
{ ulRightVerticeX, ulRightVerticeY } };
DC.Polygon(aPoints, 3);
// Restore the brush
DC.SelectObject(pOldBrush);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -