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