YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
XD++ Library
DocVizor
TFC Library
Free Products
Technical Support
UCanCode.net


Get Ready to Unleash the Power of UCanCode .NET


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


 

GDI Topics: Using a Trajectory

 
 

Introduction

 

A trajectory is a path along which an object travels. In one example, an object could go from one point to another without coming back. In another example, an object could go back and forth from one object to another. The study or implementation of trajectories is common in graphics applications, in games, or other simulation types.

Practical Learning Practical Learning: Introducing Trajectories

 

 

  1. To start this exercise, create an MFC Application named Trajectory1
  2. Create it as a Single Document type
  3. To fill the window's content with a black background, access the source file of the view and change its OnDraw event as follows:
     
    void CTrajectory1View::OnDraw(CDC* pDC)
    {
    	CTrajectory1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    
    	// TODO: add draw code for native data here
    	CBrush brsBlack;
    	CRect rctClient;
    
    	brsBlack.CreateSolidBrush(RGB(0, 0, 0));
    
    	GetWindowRect(&rctClient);
    
    	CBrush *pOldBrush = pDC->SelectObject(&brsBlack);
    	pDC->Rectangle(0, 0, rctClient.Width(), rctClient.Height());
    
    	pDC->SelectObject(pOldBrush);
    }
  4. Execute the application to see the result

Moving a Shape

 

The primary implementation of using a trajectory consist of moving an object or a shape along a path. To do this, you can draw the shape in response to a timer.

Practical Learning Practical Learning: Moving a Shape

 
  1. Using the Resource Symbols dialog box, create an ID named IDT_MOVE
  2. Generate the OnInitialUpdate event for the view class and use it to initialize the timer as follows:
     
    void CTrajectory1View::OnInitialUpdate()
    {
    	CView::OnInitialUpdate();
    
    	SetTimer(IDT_MOVE, 10, NULL);
    	// TODO: Add your specialized code here and/or call the base class
    }
  3. In the view header file, declare the following variables:
     
    // Trajectory1View.h : interface of the CTrajectory1View class
    //
    
    
    #pragma once
    
    
    class CTrajectory1View : public CView
    {
    protected: // create from serialization only
    	CTrajectory1View();
    	DECLARE_DYNCREATE(CTrajectory1View)
    
    // Attributes
    public:
    	CTrajectory1Doc* GetDocument() const;
    
    // Operations
    public:
    	static const int ShapeWidth  = 45;
    	static const int ShapeHeight = 15;
    	int x;
    	int y;
    	bool MovingRight;
    
    // Overrides
    public:
    	virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    
    // Implementation
    public:
    	virtual ~CTrajectory1View();
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    
    protected:
    
    // Generated message map functions
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    
    #ifndef _DEBUG  // debug version in Trajectory1View.cpp
    inline CTrajectory1Doc* CTrajectory1View::GetDocument() const
       { return reinterpret_cast<CTrajectory1Doc*>(m_pDocument); }
    #endif
  4. In the constructor of the view class, initialize the variables as follows:
     
    CTrajectory1View::CTrajectory1View()
    {
    	// TODO: add construction code here
    	x = 0;
    	y = 200;
    	MovingRight = false;
    }
  5. Change the OnDraw event as follows:
     
    void CTrajectory1View::OnDraw(CDC* pDC)
    {
    	CTrajectory1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    
    	// TODO: add draw code for native data here
    	CPen   penYellow;
    	CBrush brsBlack, brsFuchsia;
    	CRect rctClient;
    
    	brsBlack.CreateSolidBrush(RGB(0, 0, 0));
    	brsFuchsia.CreateSolidBrush(RGB(255, 0, 255));
    	penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
    
    	GetWindowRect(&rctClient);
    
    	CBrush *pOldBrush = pDC->SelectObject(&brsBlack);
    	pDC->Rectangle(0, 0, rctClient.Width(), rctClient.Height());
    
    	pOldBrush = pDC->SelectObject(&brsFuchsia);
    	CPen *pOldPen = pDC->SelectObject(&penYellow);
    	pDC->RoundRect(this->x, this->y, this->x + ShapeWidth,
    		       this->y + ShapeHeight, 5, 5);
    
    	pDC->SelectObject(pOldPen);
    	pDC->SelectObject(pOldBrush);
    }
  6. Generate the event of the WM_TIMER message for the view class and implement it as follows:
     
    void CTrajectory1View::OnTimer(UINT_PTR nIDEvent)
    {
    	// TODO: Add your message handler code here and/or call default
    	CRect rctClient;
    
    	GetWindowRect(&rctClient);
    
    	if( this->x < 0 )
    	{
    		this->x = 0;
    		this->MovingRight = true;
    	}
    
    	if( this->x > rctClient.Width() - ShapeWidth )
    	{
    		this->x = rctClient.Width() - ShapeWidth;
    		this->MovingRight = FALSE;
    	}
    
    	if( x < 0 )
    	{
    		x = 0;
    		MovingRight = TRUE;
    	}
    
    	if( x > rctClient.Width() - ShapeWidth )
    	{
    		x = rctClient.Width() - ShapeWidth;
    		MovingRight = FALSE;
    	}
    
    	Invalidate();
    
    	if( MovingRight == TRUE )
    		x++;
    	else
    		x--;
    
    	CView::OnTimer(nIDEvent);
    }
  7. Generate the event of the WM_ERASEBKGND message of the view class and change its return value as follows:
     
    BOOL CTrajectory1View::OnEraseBkgnd(CDC* pDC)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	return TRUE; // CView::OnEraseBkgnd(pDC);
    }
  8. Execute the application to see the result:
     
  9. Close it and return to MSVC

Creating a Shape Class

 

Object oriented programming consists of creating objects that each can perform a specific tucancode.net and take of assignments related to it. In trajectory-related programming, you can create a class for each object or shape. This can make it easy to recognize and use the object. If you happen to use different objects, you can then customize the behavior of each. 

Practical Learning Practical Learning: Creating a Shape Class

 
  1. To create a new class, on the main menu, click Project -> Add Class...
  2. In the Templates list, click C++ Class and click Add
  3. Set the Class Name to CShape and press Enter
  4. Change the header file as follows:
     
    #pragma once
    
    class CShape
    {
    public:
    	CShape(void);
    public:
    	~CShape(void);
    
    	static const int Width  = 45;
    	static const int Height = 15;
    	int x;
    	int y;
    	bool MovingRight;
    
    	void Draw(CDC* pDC);
    	void Move(CRect rctClient);
    };
  5. Change the source file as follows:
     
    #include "StdAfx.h"
    #include "Shape.h"
    
    CShape::CShape(void)
    	: x(0),
    	  y(150),
    	  MovingRight(false)
    {
    }
    
    CShape::~CShape(void)
    {
    }
    
    void CShape::Draw(CDC* pDC)
    {
    	CPen   penYellow;
    	CBrush brsFuchsia;
    
    	brsFuchsia.CreateSolidBrush(RGB(255, 0, 255));
    	penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
    
    	CBrush *pOldBrush = pDC->SelectObject(&brsFuchsia);
    	CPen *pOldPen = pDC->SelectObject(&penYellow);
    	pDC->RoundRect(this->x,
    		       this->y, 
    		       this->x + CShape::Width,
    		       this->y + CShape::Height,
    		       5,
    		       5);
    
    	pDC->SelectObject(pOldBrush);
    }
    
    void CShape::Move(CRect rctClient)
    {
    	if( this->x < 0 )
    	{
    		this->x = 0;
    		this->MovingRight = true;
    	}
    
    	if( this->x > rctClient.Width() - CShape::Width )
    	{
    		this->x = rctClient.Width() - CShape::Width;
    		this->MovingRight = FALSE;
    	}
    }
  6. Access the header file of the view class and change it as follows:
     
    // Trajectory2View.h : interface of the CTrajectory1View class
    //
    #pragma once
    
    #include "Shape.h"
    
    class CTrajectory1View : public CView
    {
    protected: // create from serialization only
    	CTrajectory1View();
    	DECLARE_DYNCREATE(CTrajectory1View)
    
    // Attributes
    public:
    	CTrajectory1Doc* GetDocument() const;
    
    // Operations
    public:
    	CShape *shape;
    
    // Overrides
    public:
    	. . .
    };
    
    #ifndef _DEBUG  // debug version in Trajectory2View.cpp
    inline CTrajectory1Doc* CTrajectory1View::GetDocument() const
       { return reinterpret_cast<CTrajectory1Doc*>(m_pDocument); }
    #endif
  7. Access the source file of the view class and change it as follows:
     
    // Trajectory2View.cpp : implementation of the CTrajectory1View class
    //
    
    #include "stdafx.h"
    #include "Trajectory2.h"
    
    #include "Trajectory2Doc.h"
    #include "Trajectory2View.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CTrajectory1View
    
    IMPLEMENT_DYNCREATE(CTrajectory1View, CView)
    
    BEGIN_MESSAGE_MAP(CTrajectory1View, CView)
    	// Standard printing commands
    	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
    	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
    	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
    	ON_WM_TIMER()
    	ON_WM_ERASEBKGND()
    END_MESSAGE_MAP()
    
    // CTrajectory1View construction/destruction
    
    CTrajectory1View::CTrajectory1View()
    {
    	// TODO: add construction code here
    	shape = new CShape;
    }
    
    CTrajectory1View::~CTrajectory1View()
    {
    	delete shape;
    }
    
    BOOL CTrajectory1View::PreCreateWindow(CREATESTRUCT& cs)
    {
    	// TODO: Modify the Window class or styles here by modifying
    	//  the CREATESTRUCT cs
    
    	return CView::PreCreateWindow(cs);
    }
    
    // CTrajectory1View drawing
    
    void CTrajectory1View::OnDraw(CDC* pDC)
    {
    	CTrajectory1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    
    	// TODO: add draw code for native data here
    	CPen   penYellow;
    	CBrush brsBlack, brsFuchsia;
    	CRect rctClient;
    
    	brsBlack.CreateSolidBrush(RGB(0, 0, 0));
    	brsFuchsia.CreateSolidBrush(RGB(255, 0, 255));
    	penYellow.CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
    
    	GetWindowRect(&rctClient);
    
    	CBrush *pOldBrush = pDC->SelectObject(&brsBlack);
    	pDC->Rectangle(0, 0, rctClient.Width(), rctClient.Height());
    
    	shape->Draw(pDC);
    
    	pDC->SelectObject(pOldBrush);
    }
    
    . . .
    
    // CTrajectory1View message handlers
    
    void CTrajectory1View::OnTimer(UINT_PTR nIDEvent)
    {
    	// TODO: Add your message handler code here and/or call default
    	CRect rctClient;
    
    	GetWindowRect(&rctClient);
    	shape->Move(rctClient);
    
    	Invalidate();
    
    	if( shape->MovingRight == TRUE )
    		shape->x++;
    	else
    		shape->x--;
    
    	CView::OnTimer(nIDEvent);
    }
    
    void CTrajectory1View::OnInitialUpdate()
    {
    	CView::OnInitialUpdate();
    
    	SetTimer(IDT_MOVE, 10, NULL);
    	// TODO: Add your specialized code here and/or call the base class
    }
    
    BOOL CTrajectory1View::OnEraseBkgnd(CDC* pDC)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	return TRUE; // CView::OnEraseBkgnd(pDC);
    }
  8. Execute the application and notice that it produces the same result

 

 

Copyright ?1998-2005 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net