精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● VB和Basic>>〓〓..技术文章连载..〓〓>>MFC消息机制>>[转载自白云黄鹤]MFC消息机制(一)

主题:[转载自白云黄鹤]MFC消息机制(一)
发信人: sodo()
整理人: cobe(1999-12-17 10:23:54), 站内信件
MFC剖析:消息机制 


首先,让我们看一下MFC的消息循环部分: 
(程序取自MFC源程序,由于篇幅,我删去了一些非重要的部分。) 
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); 


int AFXAPI AfxWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 

LPTSTR lpCmdLine, int nCmdShow) 

int nReturnCode = -1; 
CWinApp* pApp = AfxGetApp(); 

// ...... 

// Perform specific initializations 
if (!pApp->InitInstance()) 

// ...... 

//初始化实例不成功,通常一个Dialog Based MFC程序必须返回FALSE 
//这样就可以跳过消息循环。 
nReturnCode = pApp->ExitInstance(); 
goto InitFailure; 


nReturnCode = pApp->Run(); //进入消息循环部分 

InitFailure: 
// ...... 

// 程序结束 
AfxWinTerm(); 
return nReturnCode; 


int CWinApp::Run() 

// ...... 
return CWinThread::Run(); // 消息循环被封装在CWinThread类里。 


int CWinThread::Run() 

BOOL bIdle = TRUE; 
LONG lIdleCount = 0; 

// 死循环,只有收到 WM_QUIT 消息后才会退出。 
for (;;) 

while (bIdle && 
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) 

if (!OnIdle(lIdleCount++)) 
bIdle = FALSE; 

// 如果消息队列中没有消息,那么就调用OnIdle函数 
// 否则,发送消息 
do 

if (!PumpMessage()) 
// PumpMessage函数仅在收到WM_QUIT消息才返回FALSE 
return ExitInstance(); // 退出死循环 

if (IsIdleMessage(&m_msgCur)) 

bIdle = TRUE; 
lIdleCount = 0; 

} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); 
// 这段程序不仅完成了消息的发送,还实现了Idle功能。 
// GetMessage函数在消息队列中没有消息时,将不会返回, 
// 而是将控制权交给操作系统,直到消息队列中有消息为止。 
// 这段程序在一开始就调用PeekMessage函数来检测消息队列中 
// 是否有消息存在,如果存在就发送消息, 
// 否则就意味着空闲,那么就调用OnIdle函数, 
// 这样做,控制权永远不会交给操作系统。 
// 由于Windows 95, NT都是抢占式的操作系统, 
// 系统会自动进行任务切换。 
// 所以不用担心别的程序不会被运行。 



BOOL CWinThread::PumpMessage() 

if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) 
{// 收到 WM_QUIT 消息,就返回 FALSE。 
return FALSE; 


// 否则就发送消息 
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur)


::TranslateMessage(&m_msgCur); 
::DispatchMessage(&m_msgCur); 

return TRUE; 



主程序的流程: 

(程序开始) 



WinMain 



AfxWinMain 


v FALSE 
CWinApp::InitInstance-------> 退出程序 

|TRUE 


CWinApp::Run 



CWinThread::Run 

|<----------------------------+
v FALSE |
PeekMessage------->OnIdle--------+ 
|TRUE | 
|<-------------------------+ |
v | |
GetMessage | |
| | |
| | |
YES v | |
+-----WM_QUIT 消息? | |
| | | |
| |NO | |
| v | |
| TranslateMessage | |
| | | |
| | | |
| v | |
| DispatchMessage | |
| | | |
| | | |
| v TRUE | |
| PeekMessage------------------>+ | 
| | | 
| |FALSE | 
| +-----------------------------+ 


(程序结束) 


.......................................................... continued 

--
十年磨一剑,霜寒未曾试;
今日拔剑问,谁有不平事?
        ----老猫

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.47.234]

[关闭][返回]