www.gusucode.com > eMule电驴下载VC++源代码-源码程序 > eMule电驴下载VC++源代码-源码程序\code\srchybrid\GDIThread.cpp
//Download by http://www.NewXing.com //this file is part of eMule //Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either //version 2 of the License, or (at your option) any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "GDIThread.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // critical section to protect while drawing to the DC CCriticalSection CGDIThread::m_csGDILock; // m_hAnotherDead is used to signal that one or more threads have ended // (it is an auto-reset event; and starts out not signaled) //HANDLE CGDIThread::m_hAnotherDead = CreateEvent(NULL, FALSE, FALSE, NULL); ///////////////////////////////////////////////////////////////////////////// // CGDIThread IMPLEMENT_DYNAMIC(CGDIThread, CWinThread) BEGIN_MESSAGE_MAP(CGDIThread, CWinThread) //{{AFX_MSG_MAP(CGDIThread) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() CGDIThread::CGDIThread(CWnd* pWnd, HDC hDC) { m_bAutoDelete = FALSE; m_pMainWnd = pWnd; m_hDC = hDC; m_nDelay = 50; m_nScrollInc = SCROLL_UP; m_bWaitVRT = FALSE; // kill event starts out in the signaled state m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventDead = CreateEvent(NULL, TRUE, FALSE, NULL); } // The reason we don't just get a CDC from our owner and simply use it is because // MFC GDI objects can't be passed between threads. So we must instead pass a // handle and then reconvert them back to MFC objects. The reason for this is // because MFC maintains a list of all GDI objects on a per thread basis. So if // you pass a GDI object to another thread, it won't be in the correct list // and MFC will assert. BOOL CGDIThread::InitInstance() { // thread setup m_dc.Attach(m_hDC); // loop but check for kill notification while (WaitForSingleObject(m_hEventKill, 0) == WAIT_TIMEOUT) SingleStep(); // thread cleanup m_dc.Detach(); // avoid entering standard message loop by returning FALSE return FALSE; } void CGDIThread::Delete() { // calling the base here won't do anything but it is a good habit CWinThread::Delete(); // acknowledge receipt of kill notification VERIFY(SetEvent(m_hEventDead)); //VERIFY(SetEvent(m_hAnotherDead)); // what is this good for? nobody is waiting on that event! } CGDIThread::~CGDIThread() { CloseHandle(m_hEventKill); CloseHandle(m_hEventDead); //CloseHandle(m_hAnotherDead); } void CGDIThread::KillThread() { // Note: this function is called in the context of other threads, // not the thread itself. // reset the m_hEventKill which signals the thread to shutdown VERIFY(SetEvent(m_hEventKill)); // allow thread to run at higher priority during kill process SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL); WaitForSingleObject(m_hEventDead, INFINITE); WaitForSingleObject(m_hThread, INFINITE); // now delete CWinThread object since no longer necessary delete this; } ///////////////////////////////////////////////////////////////////////////// // CGDIThread message handlers int CGDIThread::SetDelay(int nDelay) { int nTmp = m_nDelay; m_nDelay = nDelay; return nTmp; } int CGDIThread::SetScrollDirection(int nDirection) { int nTmp = m_nScrollInc; m_nScrollInc = nDirection; return nTmp; } BOOL CGDIThread::SetWaitVRT(BOOL bWait) { BOOL bTmp = m_bWaitVRT; m_bWaitVRT = bWait; return bTmp; }