www.pudn.com > Thread_simple1.zip > ThreadDemo1View.cpp


// ThreadDemo1View.cpp : implementation of the CThreadDemo1View class 
// 
 
#include "stdafx.h" 
#include "ThreadDemo1.h" 
 
#include "ThreadDemo1Doc.h" 
#include "ThreadDemo1View.h" 
 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CThreadDemo1View 
 
IMPLEMENT_DYNCREATE(CThreadDemo1View, CView) 
 
BEGIN_MESSAGE_MAP(CThreadDemo1View, CView) 
	//{{AFX_MSG_MAP(CThreadDemo1View) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
UINT ThreadProc( LPVOID lpParam ) 
{ 
	// Get a THREAD_INFO pointer from the 
	// parameter that was passed in. 
	THREAD_INFO *lpThreadInfo = 
		(THREAD_INFO *) lpParam; 
 
	// The next six variables represent 
	// values used to draw the spirograph; 
	unsigned char Red, Green, Blue; 
	int nFixedRadius = 80; 
	int nMovingRadius = 10; 
	int nMovingOffset = 70; 
 
	// Begin colors based on the system time. This 
	// makes the color somewhat random. 
	Red = (unsigned char) 
		( GetTickCount() & 0x000000ff ); 
	Green = (unsigned char) 
		( ( GetTickCount() & 0x00000ff0 ) >> 4 ); 
	Blue = (unsigned char) 
		( ( GetTickCount() & 0x0000ff00 ) >> 8 ); 
 
	while( *lpThreadInfo->lpKillThread == FALSE ){ 
 
		// Get a DC for the window. 
		HDC hdc = ::GetDC( lpThreadInfo->hWnd ); 
 
		// Get the client rect so we can 
		// calculate the center point. 
		RECT Rect; 
		::GetClientRect( lpThreadInfo->hWnd, &Rect ); 
		int nMidx = Rect.right / 2; 
		int nMidy = Rect.bottom / 2; 
 
		// Clear the window. 
		::InvalidateRect( lpThreadInfo->hWnd, NULL, TRUE ); 
		::UpdateWindow( lpThreadInfo->hWnd ); 
 
		// Create a pen based on the color. Select it 
		// into the DC and remember the old pen so 
		// we can select it back in later. 
		HPEN hPen, hOldPen; 
		hPen = 
			::CreatePen( PS_SOLID, 1, RGB( Red, Green, Blue ) ); 
		hOldPen = (HPEN) ::SelectObject( hdc, hPen ); 
 
		// Iterate through a bunch of times and 
		// draw the spirograph. 
		int prevx, prevy, x = 0, y = 0; 
		for( int i=0; i<=500; i++ ){ 
 
			// Remember x and y. 
			prevx = x; 
			prevy = y; 
 
			// Calculate the new x and y. 
			x = (int) ( ( nFixedRadius + nMovingRadius ) * 
				cos( (double) i ) - 
				( nMovingRadius + nMovingOffset ) * 
				cos((double)(( ( nFixedRadius + nMovingRadius ) / 
				nMovingRadius ) * i ) ) ); 
			y = (int) ( ( nFixedRadius + nMovingRadius ) * 
				sin( (double) i ) - 
				( nMovingRadius + nMovingOffset ) * 
				sin((double)(( ( nFixedRadius + nMovingRadius ) / 
				nMovingRadius ) * i ) ) ); 
 
			// Draw the line (or move to the first 
			// point if this is the first time through). 
			if( i > 0 ) 
				::LineTo( hdc, x + nMidx, y + nMidy ); 
			else 
				::MoveToEx( hdc, x + nMidx, y + nMidy, NULL ); 
 
			} 
 
		// Increment the color variables so 
		// that the colors move around. 
		Red += 6; 
		Green += 5; 
		Blue += 4; 
 
		// Increase the fixed radius and 
		// limit it to a max of 150. 
		nFixedRadius++; 
		if( nFixedRadius > 170 ) 
			nFixedRadius = 90; 
		// Increase the moving radius and 
		// limit it to a max of 120. 
		nMovingRadius++; 
		if( nMovingRadius > 40 ) 
			nMovingRadius = 10; 
 
		// Increase the moving offset and 
		// limit it to a max of 90. 
		nMovingOffset++; 
		if( nMovingOffset > 100 ) 
			nMovingOffset = 70; 
 
		// Select the old pen into the DC, 
		// delete the pen we created, and 
		// release the DC we got. 
		::SelectObject( hdc, hOldPen ); 
		::DeleteObject( hPen ); 
		::ReleaseDC( lpThreadInfo->hWnd, hdc ); 
 
		// Sleep so we don't chew up too 
		// much CPU time. 
		Sleep( 200 ); 
		} 
 
	return( 0 ); 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CThreadDemo1View construction/destruction 
 
CThreadDemo1View::CThreadDemo1View() 
{ 
 
	// This is the flag that tells the 
	// thread to quit. 
	m_bKillThread = FALSE; 
 
	// NULL the pointer to the thread so 
	// we know it hasn't been created. 
	m_pThread = NULL; 
 
} 
 
CThreadDemo1View::~CThreadDemo1View() 
{ 
	// Get the thread handle into local space since 
	// the thread will delete itself. 
	HANDLE hThread = m_pThread->m_hThread; 
 
	// Set the flag to kill the thread to TRUE; 
	m_bKillThread = TRUE; 
 
	// Wait for the thread to end. 
	::WaitForSingleObject( hThread, 5000 ); 
 
} 
 
BOOL CThreadDemo1View::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CThreadDemo1View drawing 
 
void CThreadDemo1View::OnDraw(CDC* pDC) 
{ 
	CThreadDemo1Doc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	// If the m_pThread is NULL, we need to kick 
	// off the thread. 
	if( m_pThread == NULL ){ 
 
		// Store the window handle and the Kill flag. 
		m_ThreadInfo.hWnd = m_hWnd; 
		m_ThreadInfo.lpKillThread = &m_bKillThread; 
 
		// Start the thread. 
		m_pThread = 
			AfxBeginThread(ThreadProc, (LPVOID) &m_ThreadInfo); 
		} 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CThreadDemo1View diagnostics 
 
#ifdef _DEBUG 
void CThreadDemo1View::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CThreadDemo1View::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CThreadDemo1Doc* CThreadDemo1View::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CThreadDemo1Doc))); 
	return (CThreadDemo1Doc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CThreadDemo1View message handlers