⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thrdcore.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"
#include <process.h>    // for _beginthreadex and _endthreadex
#include <ddeml.h>  // for MSGF_DDEMGR

#ifdef AFX_CORE1_SEG
#pragma code_seg(AFX_CORE1_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Thread entry point

#ifdef _MT

struct _AFX_THREAD_STARTUP
{
	// following are "in" parameters to thread startup
	_AFX_THREAD_STATE* pThreadState;    // thread state of parent thread
	CWinThread* pThread;    // CWinThread for new thread
	DWORD dwCreateFlags;    // thread creation flags
	_PNH pfnNewHandler;     // new handler for new thread

	HANDLE hEvent;          // event triggered after success/non-success
	HANDLE hEvent2;         // event triggered after thread is resumed

	// strictly "out" -- set after hEvent is triggered
	BOOL bError;    // TRUE if error during startup
};

UINT APIENTRY _AfxThreadEntry(void* pParam)
{
	_AFX_THREAD_STARTUP* pStartup = (_AFX_THREAD_STARTUP*)pParam;
	ASSERT(pStartup != NULL);
	ASSERT(pStartup->pThreadState != NULL);
	ASSERT(pStartup->pThread != NULL);
	ASSERT(pStartup->hEvent != NULL);
	ASSERT(!pStartup->bError);

	CWinThread* pThread = pStartup->pThread;
	CWnd threadWnd;
	TRY
	{
		// inherit parent's module state
		_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
		pThreadState->m_pModuleState = pStartup->pThreadState->m_pModuleState;

		// set current thread pointer for AfxGetThread
		AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
#ifdef _AFXDLL
		pThread->m_pModuleState = pModuleState;
#endif
		AFX_MODULE_THREAD_STATE* pState = pModuleState->m_thread;
		pState->m_pCurrentWinThread = pThread;

		// forced initialization of the thread
		AfxInitThread();

		// thread inherits app's main window if not already set
		CWinApp* pApp = AfxGetApp();
		if (pApp != NULL &&
			pThread->m_pMainWnd == NULL && pApp->m_pMainWnd->GetSafeHwnd() != NULL)
		{
			// just attach the HWND
			threadWnd.Attach(pApp->m_pMainWnd->m_hWnd);
			pThread->m_pMainWnd = &threadWnd;
		}
	}
	CATCH_ALL(e)
	{
		// Note: DELETE_EXCEPTION(e) not required.

		// exception happened during thread initialization!!
		TRACE0("Warning: Error during thread initialization!\n");

		// set error flag and allow the creating thread to notice the error
		threadWnd.Detach();
		pStartup->bError = TRUE;
		VERIFY(::SetEvent(pStartup->hEvent));
		AfxEndThread((UINT)-1, FALSE);
		ASSERT(FALSE);  // unreachable
	}
	END_CATCH_ALL

	// pStartup is invaid after the following SetEvent (but hEvent2 is valid)
	HANDLE hEvent2 = pStartup->hEvent2;

	// allow the creating thread to return from CWinThread::CreateThread
	VERIFY(::SetEvent(pStartup->hEvent));

	// wait for thread to be resumed
	VERIFY(::WaitForSingleObject(hEvent2, INFINITE) == WAIT_OBJECT_0);
	::CloseHandle(hEvent2);

	// first -- check for simple worker thread
	DWORD nResult = 0;
	if (pThread->m_pfnThreadProc != NULL)
	{
		nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);
		ASSERT_VALID(pThread);
	}
	// else -- check for thread with message loop
	else if (!pThread->InitInstance())
	{
		ASSERT_VALID(pThread);
		nResult = pThread->ExitInstance();
	}
	else
	{
		// will stop after PostQuitMessage called
		ASSERT_VALID(pThread);
		nResult = pThread->Run();
	}

	// cleanup and shutdown the thread
	threadWnd.Detach();
	AfxEndThread(nResult);

	return 0;   // not reached
}

#endif //_MT

CWinThread* AFXAPI AfxGetThread()
{
	// check for current thread in module thread state
	AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
	CWinThread* pThread = pState->m_pCurrentWinThread;

	// if no CWinThread for the module, then use the global app
	if (pThread == NULL)
		pThread = AfxGetApp();

	return pThread;
}

CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
	int nPriority, UINT nStackSize, DWORD dwCreateFlags,
	LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
	pfnThreadProc;
	pParam;
	nPriority;
	nStackSize;
	dwCreateFlags;
	lpSecurityAttrs;

	return NULL;
#else
	ASSERT(pfnThreadProc != NULL);

	CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
	ASSERT_VALID(pThread);

	if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
		lpSecurityAttrs))
	{
		pThread->Delete();
		return NULL;
	}
	VERIFY(pThread->SetThreadPriority(nPriority));
	if (!(dwCreateFlags & CREATE_SUSPENDED))
		VERIFY(pThread->ResumeThread() != (DWORD)-1);

	return pThread;
#endif //!_MT)
}

CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,
	int nPriority, UINT nStackSize, DWORD dwCreateFlags,
	LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
	pThreadClass;
	nPriority;
	nStackSize;
	dwCreateFlags;
	lpSecurityAttrs;

	return NULL;
#else
	ASSERT(pThreadClass != NULL);
	ASSERT(pThreadClass->IsDerivedFrom(RUNTIME_CLASS(CWinThread)));

	CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();
	if (pThread == NULL)
		AfxThrowMemoryException();
	ASSERT_VALID(pThread);

	pThread->m_pThreadParams = NULL;
	if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
		lpSecurityAttrs))
	{
		pThread->Delete();
		return NULL;
	}
	VERIFY(pThread->SetThreadPriority(nPriority));
	if (!(dwCreateFlags & CREATE_SUSPENDED))
		VERIFY(pThread->ResumeThread() != (DWORD)-1);

	return pThread;
#endif //!_MT
}

void AFXAPI AfxEndThread(UINT nExitCode, BOOL bDelete)
{
#ifndef _MT
	nExitCode;
	bDelete;
#else
	// remove current CWinThread object from memory
	AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
	CWinThread* pThread = pState->m_pCurrentWinThread;
	if (pThread != NULL)
	{
		ASSERT_VALID(pThread);
		ASSERT(pThread != AfxGetApp());

		// cleanup OLE if required
		if (pThread->m_lpfnOleTermOrFreeLib != NULL)
			(*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE);

		if (bDelete)
			pThread->Delete();
		pState->m_pCurrentWinThread = NULL;
	}

	// allow cleanup of any thread local objects
	AfxTermThread();

	// allow C-runtime to cleanup, and exit the thread
	_endthreadex(nExitCode);
#endif //!_MT
}

/////////////////////////////////////////////////////////////////////////////
// Global functions for thread initialization and thread cleanup

LRESULT CALLBACK _AfxMsgFilterHook(int code, WPARAM wParam, LPARAM lParam);

void AFXAPI AfxInitThread()
{
	if (!afxContextIsDLL)
	{
		// set message filter proc
		_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
		ASSERT(pThreadState->m_hHookOldMsgFilter == NULL);
		pThreadState->m_hHookOldMsgFilter = ::SetWindowsHookEx(WH_MSGFILTER,
			_AfxMsgFilterHook, NULL, ::GetCurrentThreadId());

#ifndef _AFX_NO_CTL3D_SUPPORT
		// intialize CTL3D for this thread
		_AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState;
		if (pCtl3dState->m_pfnAutoSubclass != NULL)
			(*pCtl3dState->m_pfnAutoSubclass)(AfxGetInstanceHandle());

		// allocate thread local _AFX_CTL3D_THREAD just for automatic termination
		_AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread;
		pTemp;  // avoid unused warning
#endif
	}
}

extern CThreadSlotData* _afxThreadData;
void AFXAPI AfxTermThread(HINSTANCE hInstTerm)
{
	try
	{
#ifdef _DEBUG
		// check for missing AfxLockTempMap calls
		if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
		{
			TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
				AfxGetModuleThreadState()->m_nTempMapLock);
		}
#endif
		AfxLockTempMaps();
		AfxUnlockTempMaps(-1);

		// cleanup thread local tooltip window
		if (hInstTerm == NULL)
		{
			_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetDataNA();
			if ((pThreadState != NULL) &&
				(pThreadState->m_pToolTip != NULL))
			{
				pThreadState->m_pToolTip->DestroyWindow();
				delete pThreadState->m_pToolTip;
				pThreadState->m_pToolTip=NULL;
			}
		}

		// cleanup the rest of the thread local data
		if (_afxThreadData != NULL)
			_afxThreadData->DeleteValues(hInstTerm, FALSE);
	}
	catch( CException* e )
	{
		e->Delete();
	}
}

/////////////////////////////////////////////////////////////////////////////
// CWinThread construction

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

CWinThread::CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam)
{
	m_pfnThreadProc = pfnThreadProc;
	m_pThreadParams = pParam;

	CommonConstruct();
}

CWinThread::CWinThread()
{
	m_pThreadParams = NULL;
	m_pfnThreadProc = NULL;

	CommonConstruct();
}

void CWinThread::CommonConstruct()
{
	m_pMainWnd = NULL;
	m_pActiveWnd = NULL;

	// no HTHREAD until it is created
	m_hThread = NULL;
	m_nThreadID = 0;

	// initialize message pump
#ifdef _DEBUG
	m_nDisablePumpCount = 0;
#endif
	m_msgCur.message = WM_NULL;
	m_nMsgLast = WM_NULL;
	::GetCursorPos(&m_ptCursorLast);

	// most threads are deleted when not needed
	m_bAutoDelete = TRUE;

	// initialize OLE state
	m_pMessageFilter = NULL;
	m_lpfnOleTermOrFreeLib = NULL;
}

#ifdef AFX_TERM_SEG
#pragma code_seg(AFX_TERM_SEG)
#endif

CWinThread::~CWinThread()
{
	// free thread object
	if (m_hThread != NULL)
		CloseHandle(m_hThread);

	// cleanup module state
	AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
	if (pState->m_pCurrentWinThread == this)
		pState->m_pCurrentWinThread = NULL;
}

#ifdef AFX_CORE1_SEG
#pragma code_seg(AFX_CORE1_SEG)
#endif

BOOL CWinThread::CreateThread(DWORD dwCreateFlags, UINT nStackSize,
	LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
	dwCreateFlags;
	nStackSize;
	lpSecurityAttrs;

	return FALSE;
#else
	ASSERT(m_hThread == NULL);  // already created?

	// setup startup structure for thread initialization
	_AFX_THREAD_STARTUP startup; memset(&startup, 0, sizeof(startup));
	startup.pThreadState = AfxGetThreadState();
	startup.pThread = this;
	startup.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
	startup.hEvent2 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
	startup.dwCreateFlags = dwCreateFlags;
	if (startup.hEvent == NULL || startup.hEvent2 == NULL)
	{
		TRACE0("Warning: CreateEvent failed in CWinThread::CreateThread.\n");
		if (startup.hEvent != NULL)
			::CloseHandle(startup.hEvent);
		if (startup.hEvent2 != NULL)
			::CloseHandle(startup.hEvent2);
		return FALSE;
	}

	// create the thread (it may or may not start to run)
	m_hThread = (HANDLE)_beginthreadex(lpSecurityAttrs, nStackSize,
		&_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);
	if (m_hThread == NULL)
		return FALSE;

	// start the thread just for MFC initialization
	VERIFY(ResumeThread() != (DWORD)-1);
	VERIFY(::WaitForSingleObject(startup.hEvent, INFINITE) == WAIT_OBJECT_0);
	::CloseHandle(startup.hEvent);

	// if created suspended, suspend it until resume thread wakes it up
	if (dwCreateFlags & CREATE_SUSPENDED)
		VERIFY(::SuspendThread(m_hThread) != (DWORD)-1);

	// if error during startup, shut things down
	if (startup.bError)
	{
		VERIFY(::WaitForSingleObject(m_hThread, INFINITE) == WAIT_OBJECT_0);
		::CloseHandle(m_hThread);
		m_hThread = NULL;
		::CloseHandle(startup.hEvent2);
		return FALSE;
	}

	// allow thread to continue, once resumed (it may already be resumed)
	::SetEvent(startup.hEvent2);
	return TRUE;
#endif //!_MT
}

void CWinThread::Delete()
{
	// delete thread if it is auto-deleting
	if (m_bAutoDelete)
		delete this;
}

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -