我是靠谱客的博主 传统铃铛,最近开发中收集的这篇文章主要介绍MFC中的线程与消息,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、MFC程序的进入点其实是WinMain,源代码如下:

extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine, int nCmdShow)
{
	// call shared/exported WinMain
	return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
_tWinMain的定义:#define _tWinMain   WinMain


2、程序然后,进入AfxWinMain(...)函数,在此函数中初始化线程,并建立消息循环。AfxWinMain源代码如下

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);

int nReturnCode = -1;

CWinThread* pThread= AfxGetThread();
CWinApp* pApp = AfxGetApp();

        //其实pThread和pApp是指向同一个对象,都取出来是因为要分别调用各类中的函数


// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;

// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;

        /*窗口类只需注册一次,即可供同一程序的后续每一个实例(instance)使用(之所以如此,是因为所有进程同在一个地址空间中),所以我们把RegisterClass这个操作           安排在“只有第一个实例才会进入”的InitApplication函数中。 · 产生窗口,是每一个实例都得进行的操作,所以我们把CreateWindow这个操作安排在“任何实例都会进入”的           InitInstance函数中。*/

// Perform specific initializations
if (!pThread->InitInstance())//InitInstance()每一个应用程序实例都会调用一次
{
if (pThread->m_pMainWnd != NULL)
{
TRACE0("Warning: Destroying non-NULL m_pMainWndn");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();//在Run中启动线程的消息循环

InitFailure:
#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);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif

AfxWinTerm();
return nReturnCode;
}

线程对象是在程序进入启动点_tWinMain之前,以全局对象的形式建立的,如下:

CTestApp theApp;

pThread->Run()中Run函数源代码:

int CWinThread::Run()
{
	ASSERT_VALID(this);

	// for tracking the idle time state
	BOOL bIdle = TRUE;
	LONG lIdleCount = 0;

	// acquire and dispatch messages until a WM_QUIT message is received.
	for (;;)
	{
		// phase1: check to see if we can do idle work
		while (bIdle &&
			!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
		{
			// call OnIdle while in bIdle state
			if (!OnIdle(lIdleCount++))
				bIdle = FALSE; // assume "no idle" state
		}

		// phase2: pump messages while available
		do
		{
			// pump message, but quit on WM_QUIT
			if (!PumpMessage())
				return ExitInstance();

			// reset "no idle" state after pumping "normal" message
			if (IsIdleMessage(&m_msgCur))
			{
				bIdle = TRUE;
				lIdleCount = 0;
			}

		} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
	}

	ASSERT(FALSE);  // not reachable
}


最后

以上就是传统铃铛为你收集整理的MFC中的线程与消息的全部内容,希望文章能够帮你解决MFC中的线程与消息所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部