您的位置:首页 > 其它

多线程演示程序(MFC)

2006-02-06 15:25 211 查看
// ThreadDemo1View.h : interface of the CThreadDemo1View class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_THREADDEMO1VIEW_H__3CAF4D6E_8775_11D1_B719_00C0A83735D8__INCLUDED_)
#define AFX_THREADDEMO1VIEW_H__3CAF4D6E_8775_11D1_B719_00C0A83735D8__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

typedef struct
{
HWND hWnd;
BOOL *lpKillThread;
} THREAD_INFO;

class CThreadDemo1View : public CView
{
protected: // create from serialization only
CThreadDemo1View();
DECLARE_DYNCREATE(CThreadDemo1View)

// Attributes
public:
CThreadDemo1Doc* GetDocument();

BOOL m_bKillThread;
CWinThread *m_pThread;
THREAD_INFO m_ThreadInfo;

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CThreadDemo1View)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CThreadDemo1View();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
//{{AFX_MSG(CThreadDemo1View)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG // debug version in ThreadDemo1View.cpp
inline CThreadDemo1Doc* CThreadDemo1View::GetDocument()
{ return (CThreadDemo1Doc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_THREADDEMO1VIEW_H__3CAF4D6E_8775_11D1_B719_00C0A83735D8__INCLUDED_)

// ThreadDemo1View.cpp : implementation of the CThreadDemo1View class
//

#include "stdafx.h"
#include "ThreadDemo1.h"

#include "ThreadDemo1Doc.h"
#include "ThreadDemo1View.h"

#include <math.h>

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: