www.pudn.com > BesidesFTPServer.rar > StarWarsCtrl.cpp


/****************************************************************/ 
/*																*/ 
/*  StarWarsCtrl.cpp											*/ 
/*																*/ 
/*  Implementation of the CStarWarsCtrl.cpp class.				*/ 
/*																*/ 
/*  Programmed by Pablo van der Meer							*/ 
/*  Copyright Pablo Software Solutions 2002						*/ 
/*  http://www.pablovandermeer.nl								*/ 
/*																*/ 
/*  Last updated: 19 Oktober 2002								*/ 
/*																*/ 
/****************************************************************/ 
 
 
#include "stdafx.h" 
#include "StarWarsCtrl.h" 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define getrandom(min,max) ((rand()%(int)(((max)+1)-(min)))+(min)); 
 
 
CStarWarsCtrl::CStarWarsCtrl() 
{ 
	// protected bitmaps to restore the memory DC's 
	m_pOldBitmap = NULL; 
 
	m_Font.CreateFont(22, 0, 0, 0, FW_BOLD, 
                       FALSE, FALSE, 0, ANSI_CHARSET, 
                       OUT_DEFAULT_PRECIS,  
                       CLIP_DEFAULT_PRECIS, 
                       DEFAULT_QUALITY,  
                       DEFAULT_PITCH|FF_SWISS, "Tahoma"); 
	m_nScrollSpeed = 3; 
	m_nStarsSpeed = 30; 
} 
 
CStarWarsCtrl::~CStarWarsCtrl() 
{ 
	if (m_pOldBitmap != NULL) 
		m_MainDC.SelectObject(m_pOldBitmap);   
} 
 
 
BEGIN_MESSAGE_MAP(CStarWarsCtrl, CStatic) 
	//{{AFX_MSG_MAP(CStarWarsCtrl) 
	ON_WM_PAINT() 
	ON_WM_SIZE() 
	ON_WM_TIMER() 
	ON_WM_LBUTTONDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : PreSubclassWindow								*/ 
/* Description   : Initialize some stuff							*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::PreSubclassWindow()  
{ 
	CClientDC dc(this); 
 
	GetClientRect(m_rectClient); 
 
	// initialize stars 
	for (int i = 0; i < NUM_STARS; i++) 
	{ 
		m_StarArray[i].x = getrandom(0, 1024); 
		m_StarArray[i].x -= 512; 
		m_StarArray[i].y = getrandom(0, 1024); 
		m_StarArray[i].y -= 512; 
		m_StarArray[i].z = getrandom(0, 512); 
		m_StarArray[i].z -= 256; 
	} 
 
	m_nScrollPos = m_rectClient.Height(); 
 
	// calculate speed so that it scroll the same speed on a different machine 
	DWORD t1 = GetTickCount(); 
	InvalidateCtrl(); 
	DWORD t2 = GetTickCount(); 
 
	t2 -= t1; // = 50 on my system 
 
	m_nScrollSpeed = (m_nScrollSpeed * t2)/50; 
 
	SetTimer(1, 100, NULL); 
 
	CStatic::PreSubclassWindow(); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnPaint											*/ 
/* Description   : Called when the application makes a request to	*/ 
/*				   repaint a portion of the window.					*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	CDC memDC; 
	CBitmap memBitmap; 
	CBitmap* oldBitmap; 
 
	// to avoid flicker, establish a memory dc, draw to it  
	// and then BitBlt it to the client 
	memDC.CreateCompatibleDC(&dc); 
	memBitmap.CreateCompatibleBitmap(&dc, m_rectClient.Width(), m_rectClient.Height()); 
	oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap); 
 
	if (memDC.GetSafeHdc() != NULL) 
	{ 
		// first drop the bitmap on the memory dc 
		memDC.BitBlt(0, 0, m_rectClient.Width(), m_rectClient.Height(), &m_MainDC, 0, 0, SRCCOPY); 
		// finally send the result to the display 
		dc.BitBlt(0, 0, m_rectClient.Width(), m_rectClient.Height(), &memDC, 0, 0, SRCCOPY); 
	} 
	memDC.SelectObject(oldBitmap); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnSize											*/ 
/* Description   : The framework calls this member function after	*/ 
/*				   the window’s size has changed.					*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::OnSize(UINT nType, int cx, int cy)  
{ 
	CStatic::OnSize(nType, cx, cy); 
	 
	// OnSize automatically gets called during the setup of the control 
	GetClientRect(m_rectClient); 
 
	// destroy and recreate the main bitmap 
	CClientDC dc(this); 
	if (m_pOldBitmap && m_MainBitmap.GetSafeHandle() && m_MainDC.GetSafeHdc()) 
	{ 
		m_MainDC.SelectObject(m_pOldBitmap); 
		m_MainBitmap.DeleteObject(); 
		m_MainBitmap.CreateCompatibleBitmap(&dc, m_rectClient.Width(), m_rectClient.Height()); 
		m_pOldBitmap = m_MainDC.SelectObject(&m_MainBitmap); 
	} 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnTimer											*/ 
/* Description   : Update display									*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::OnTimer(UINT nIDEvent)  
{ 
	if (nIDEvent == 1) 
		InvalidateCtrl(); 
 
	CStatic::OnTimer(nIDEvent); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : InvalidateCtrl									*/ 
/* Description   : Draw the Matrix to a bitmap.						*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::InvalidateCtrl() 
{ 
	// in case we haven't established the memory dc's 
	CClientDC dc(this); 
 
	// if we don't have one yet, set up a memory dc for the control  
	if (m_MainDC.GetSafeHdc() == NULL) 
	{ 
		m_MainDC.CreateCompatibleDC(&dc); 
		m_MainBitmap.CreateCompatibleBitmap(&dc, m_rectClient.Width(), m_rectClient.Height()); 
		m_pOldBitmap = m_MainDC.SelectObject(&m_MainBitmap); 
	} 
 
	m_MainDC.SetBkColor(RGB(0,0,0)); 
	m_MainDC.SetTextColor(RGB(255,255,255)); 
	m_MainDC.FillSolidRect(m_rectClient, RGB(0,0,0)); 
	 
	DoStars(&dc);	 
	DoScrollText(&dc); 
 
	// finally, force redraw 
	InvalidateRect(m_rectClient); 
}  
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : DoStars											*/ 
/* Description   : Draw stars										*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::DoStars(CDC *pDC) 
{ 
	int nFunFactor = 100; 
	int x, y, z; 
	 
	for(int i = 0; i < NUM_STARS; i++) 
	{ 
        m_StarArray[i].z = m_StarArray[i].z - m_nStarsSpeed; 
	 
        if (m_StarArray[i].z > 255) 
		{ 
			m_StarArray[i].z = -255; 
		} 
        if (m_StarArray[i].z < -255) 
		{ 
			m_StarArray[i].z = 255; 
		} 
 
		z = m_StarArray[i].z + 256; 
        x = (m_StarArray[i].x * nFunFactor / z) + (m_rectClient.Width() / 2); 
        y = (m_StarArray[i].y * nFunFactor / z) + (m_rectClient.Height() / 2); 
 
		// create a white pen which luminosity depends on the z position (for 3D effect!) 
		int nColor = 255 - m_StarArray[i].z; 
		 
		// color must be between 0 and 255 
	    nColor = nColor < 0 ? 0 : nColor > 255 ? 255 : nColor; 
 
		// x must be between 0 and width 
		x = x < 0 ? 0 : x > (m_rectClient.Width()-3) ? m_rectClient.Width() : x; 
		// y must be between 0 and height 
		y = y < 0 ? 0 : y > (m_rectClient.Height()-3) ? m_rectClient.Height() : y; 
 
		CPen myPen; 
		myPen.CreatePen(PS_COSMETIC, 1, RGB(nColor,nColor,nColor)); 
 
		// draw star 
		CPen *pOldPen = (CPen *)m_MainDC.SelectObject(&myPen); 
		m_MainDC.Rectangle(x, y, x+2, y+2); 
 
//		on my XP computer this function will bring down my system... 
//		m_MainDC.Ellipse(x, y, x+3, y+3); 
 
		m_MainDC.SelectObject(pOldPen);  
    }  
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : DoScrollText										*/ 
/* Description   : Do scrolling text like in the movie 'Star Wars'	*/ 
/*																	*/ 
/********************************************************************/ 
void CStarWarsCtrl::DoScrollText(CDC *pDC) 
{ 
	int nPosX =0; 
	int nPosY =0; 
 
	CDC memDC; 
	CBitmap memBitmap; 
 
	memDC.CreateCompatibleDC(pDC); 
	memBitmap.CreateCompatibleBitmap(pDC, m_rectClient.Width(), m_rectClient.Height()); 
	 
	CBitmap *pOldBitmap = memDC.SelectObject(&memBitmap); 
	CFont *pOldFont = memDC.SelectObject(&m_Font); 
 
	memDC.SetBkColor(RGB(0,0,0)); 
	memDC.SetTextColor(RGB(0,255,0)); 
    memDC.SetBkMode(TRANSPARENT); 
	 
	// black 
	memDC.BitBlt(0, 0, m_rectClient.Width(), m_rectClient.Height(), NULL, 0, 0, BLACKNESS); 
	 
	// draw credits  
	for(int i=0; i < m_TextLines.GetSize(); i++) 
	{ 
		// set position for this line 
		CSize size = memDC.GetTextExtent(m_TextLines.GetAt(i)); 
 
		nPosY = m_nScrollPos + (i * size.cy); 
		if (nPosY > 0) 
		{ 
			nPosX = (m_rectClient.Width() / 2) - (size.cx / 2); 
 
			if (nPosY > 255) 
			{ 
				memDC.SetTextColor(RGB(255, 255, 255)); 
			} 
			else 
			{ 
				// set fade color 
				memDC.SetTextColor(RGB(nPosY, nPosY, nPosY)); 
			} 
			 
			// print text 
			memDC.TextOut(nPosX, nPosY, m_TextLines.GetAt(i)); 
		} 
		else 
		{ 
			// start all over ... 
			if (i == (m_TextLines.GetSize()-1)) 
			{ 
				m_nScrollPos = m_rectClient.Height(); 
			} 
		} 
	} 
 
	int nWidth = m_rectClient.Width(); 
	int nHeight = m_rectClient.Height(); 
 
	// shrink text from bottom to top to create Star Wars effect 
	for (int y=0; y