学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。[MFC]消息机制首先,让我们看一下MFC的消息循环部分:(程序取自MFC源程序,由于篇幅,我删去了一些非重要的部分。)MFC的WinMain函数:[c]externCintWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){//callshared/exportedWinMainreturnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);}intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){intnReturnCode=-1;CWinApp*pApp=AfxGetApp();//……//Performspecificinitializationsif(!pApp-InitInstance()){//……//初始化实例不成功,通常一个DialogBasedMFC程序必须返回FALSE//这样就可以跳过消息循环。nReturnCode=pApp-ExitInstance();gotoInitFailure;}nReturnCode=pApp-Run();//进入消息循环部分InitFailure://……//程序结束AfxWinTerm();returnnReturnCode;}intCWinApp::Run(){//……returnCWinThread::Run();//消息循环被封装在CWinThread类里。}intCWinThread::Run(){BOOLbIdle=TRUE;LONGlIdleCount=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消息才返回FALSEreturnExitInstance();//退出死循环if(IsIdleMessage(&m_msgCur)){bIdle=TRUE;lIdleCount=0;}}while(::PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_NOREMOVE));//这段程序不仅完成了消息的发送,还实现了Idle功能。//GetMessage函数在消息队列中没有消息时,将不会返回,//而是将控制权交给操作系统,直到消息队列中有消息为止。//这段程序在一开始就调用PeekMessage函数来检测消息队列中//是否有消息存在,如果存在就发送消息,//否则就意味着空闲,那么就调用OnIdle函数,//这样做,控制权永远不会交给操作系统。//由于Windows95,NT都是抢占式的操作系统,//系统会自动进行任务切换。//所以不用担心别的程序不会被运行。}}BOOLCWinThread::PumpMessage(){if(!::GetMessage(&m_msgCur,NULL,NULL,NULL)){//收到WM_QUIT消息,就返回FALSE。returnFALSE;}//否则就发送消息if(m_msgCur.message!=WM_KICKIDLE&&!PreTranslateMessage(&m_msgCur)){::TranslateMessage(&m_msgCur);::DispatchMessage(&m_msgCur);}returnTRUE;}[/c]主程序的流程:[text](程序开始)||vWinMain||vAfxWinMain||vFALSECWinApp::InitInstance——-退出程序||TRUE|vCWinApp::Run||vCWinThread::Run||—————————-+vFALSE|PeekMessage——-OnIdle——–+|TRUE||————————-+|v||GetMessage||||||||YESv||+—–WM_QUIT消息?||||||||NO|||v|||TranslateMessage|||||||||||v|||DispatchMessage|||||||||||vTRUE|||PeekMessage——————+||||||FALSE||+—————————–+|v(程序结束)[/text]现在,再让我们来看一下MFC的窗口是如何响应消息的。我们先来看一段建立一个窗口的代码.[c]classCMsgWnd:publicCWnd{public:CMsgWnd(){}//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CMsgWnd)virtualBOOLCreate(CWnd*pParentWnd);//}}AFX_VIRTUALvirtual~CMsgWnd(){}protected://{{AFX_MSG(CMsgWnd)afx_msgvoidOnPaint();afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);//}}AFX_MSGDECLARE_MESSAGE_MAP()};BEGIN_MESSAGE_MAP(CMsgWnd,CWnd)//{{AFX_MSG_MAP(CMsgWnd)ON_WM_PAINT()ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAPEND_MESSAGE_MAP()BOOLCMsgWnd::Create(CWnd*pParentWnd){returnCWnd::Create(AfxRegisterWndClass(CS_DBLCLKS),MessageWindow,WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),pParentWnd,12345);}voidCMsgWnd::OnPaint(){CPaintDCdc(this);//devicecontextforpaintingdc.TextOut(0,0,hello);}voidCMsgWnd::OnLButtonDown(UINTnFlags,CPointpoint){MessageBox(OnLButtonDown);CWnd::OnLButtonDown(nFlags,point);}[/c]以上是一段标准的CWnd窗口类的子类实现代码.我想大家应该是可以看的懂的.注意到CMsgWnd类中有一句代码DECLARE_MESSAGE_MAP()我们来看看这个宏是如何定义的:[c]typedefvoid(AFX_MSG_CALLCCmdTarget::*AFX_PMSG)(void);//这是一个指向CCmdTarget类成员函数的指针类型.structAFX_MSGMAP_ENTRY//消息映射表之消息入口{UINTnMessage;//消息UINTnCode;//控制码或者是WM_NOTIFY消息的通知码UINTnID;//控件的ID,如果是窗口消息则为0UINTnLastID;//如果是一个范围的消息,那么这是最后一个控件的IDUINTnSig;//消息处理类型AFX_PMSGpfn;//消息处理函数};structAFX_MSGMAP//消息映射表{#ifdef_AFXDLL//如果MFC是动态连接的,//就是编译时选择UseMFCinasharedDLLconstAFX_MSGMAP*(PASCAL*pfnGetBaseMap)();#else//MFC是静态连接的,编译时选择UseMFCinastaticlibrary.constAFX_MSGMAP*pBaseMap;#endif//如果MFC是动态连接的,就用pfnGetBaseMap函数返回基类的消息映射表//否则pBaseBap指向基类的消息映射表constAFX_MSGMAP_ENTRY*lpEntries;//指向消息入口的指针};#ifdef_AFXDLL//如果MFC是动态连接的#defineDECLARE_MESSAGE_MAP()\private:\staticconstAFX_MSGMAP_ENTRY_messageEntries[];\//消息入口protected:\staticAFX_DATAconstAFX_MSGMAPmessageMap;\//消息映射表staticconstAFX_MSGMAP*PASCAL_GetBaseMessageMap();\//该函数返回基类的消息映射表virtualconstAFX_MSGMAP*GetMessageMap()const;\//该函数返回当前类的消息映射表#else//静态连接的#defineDECLARE_MESSAGE_MAP()\private:\staticconstAFX_MSGMAP_ENTRY_messageEntries[];\protected:\staticAFX_DATAconstAFX_MSGMAPmessageMap;\virtualconstAFX_MSGMAP*GetMessageMap()const;\#endif//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//以上这段代码实际上是嵌入在你的类中.在.CPP文件中我们看到还有这段宏,BEGIN_MESSAGE_MAP(CMsgWnd,CWnd)//{{AFX_MSG_MAP(CMsgWnd)ON_WM_PAINT()ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAPEND_MESSAGE_MAP()现在我们再来看看它是被如何定义的.#ifdef_AFXDLL#defineBEGIN_MESSAGE_MAP(theClass,baseClass)\constAFX_MSGMAP*PASCALtheClass::_GetBaseMessageMap()\{return&baseClass::messageMap;}\//返回基类的消息映射表^^^^^^^^^^^^^^^^^^^^^^constAFX_MSGMAP*theClass::GetMessageMap()const\{return&theClass::messageMap;}\//返回当前类的消息映射表AFX_DATADEFconstAFX_MSGMAPtheClass::messageMap=\//消息映射表{&theClass::_GetBaseMessageMap,&theClass::_messageEntries[0]};\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^constAFX_MSGMAP_ENTRYtheClass::_messageEntries[]=\{\#else#defineBEGIN_MESSAGE_MAP(theClass,baseClass)\constAFX_MSGMAP*theClass::GetMessageMap()const\{return&theClass::messageMap;}\//返回当前类的消息映射表AFX_DATADEFconstAFX_MSGMAPtheClass::messageMap=\//消息映射表{&baseClass::messageM