五、MFC消息的流动 消息的起点是AfxWndProc函数,所有的消息都被发送到AfxWndProc,也从AfxWndProc再次流向各自的消息响应函数的,怎么流的呢?那只有MFC知道: LRESULT CALLBACK AfxWndProc(…….) { …… return AfxCallWndProc(pWnd,hWnd,nMsg,wParam,lParam); } LRESULT AFXAPI AfxCallWndProc(……) { …… lResult = pWnd->WindowProc(nMsg,wParam,lParam); …… } LRESULT CWnd::WindowProc(……) { …… if(!OnWndMsg(message,wParam,lParam,&lResult)) lResult = DefWindowProc(message,wParam,lParam); …… } BOOL CWnd::OnWndMsg(……)//该函数原来太过庞大,被我改造了一下,只反映意思,不能执行 { …… if(message == WM_COMMAND) OnCommand(wParam,lParam); if(message == WM_NOTIFY) OnNotify(wParam,lParam,&lResult); pMessage = GetMessageMap(); for(; pMessageMap!=NULL; pMessageMap = pMessageMap->pBaseMap) { if((lpEntry=AfxFindMessageEntry(pMessageMap->lpEntries, message,0,0))!=NULL) break; } (this->*(lpEntry->pnf))(……);//调用消息响应函数 } AFX_MSGMAP_ENTRY AfxFindMessageEntry(……) { …… while(lpEntry->nSign!=AfxSig_end) { if(lpEntry->nMessage==nMsg&&lpEntry->nCode==nCode&&nID>=lpEntry->nID &&nID<=lpEntry->nLastID) { return lpEntry; } lpEntry++; } …… }
消息被发送到对应窗口的OnWndMsg后,然后根据消息的类型采取相应动作:如果是标准消息,则检查但前类中有无处理函数(由AfxFindMessageEntry实现),若没有,就在其父亲类中找(通过pMessageMap->pBaseMap实现),这样望上顺序搜索消息网,搜索结束也找不到处理函数,那么回到WindowProc函数调用默认DefWindowProc函数;如果是命令消息或通知消息则发送到OnCommand或者OnNotify函数中去处理,来实现消息的拐弯流动: BOOL CWnd::OnCommand(WPARAM wParam,LPARAM lParam) { …… return OnCmdMsg(nID,nCode,NULL,NULL); } BOOL CFrameWnd::OnCmdMsg(……) { CView* pView = GetActiveView(); if(pView!=NULL&&pView->OnCmdMsg(……)) //相当于图1中Frame指向View的箭头 return TRUE; if(CWnd::OnCmdMsg(……)) //图1中Frame自身 return TRUE; CWinApp *pApp = AfxGetApp(); if(pApp != NULL && pApp->OnCmdMsg(……)) //图1中CWinApp对象 return TRUE; return FALSE; } BOOL CView::OnCmdMsg(……) { if(CWnd::OnCmdMsg(……)) //图1中View本身 return TRUE; if(m_pDocument!=NULL) m_pDocument->OnCmdMsg(……);//图1中View到Doc箭头 …… } BOOL CDocument::OnCmdMsg(……) { if(CCmdTarget::OnCmdMsg(……)) //图1中Doc本身 return TRUE; if(m_pDocTemplate!=NULL&&m_pDocTemplate->OnCmdMsg(……))//图1中Doc Template return TRUE; return FALSE; } BOOL CCmdTarget::OnCmdMsg(……)//注:CWnd没有重载CCmdTarget的OnCmdMsg { …… for(pMessageMap=GetMessageMap();pMessageMap!=NULL; pMessageMap=pMessageMap->pBaseMap) { lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,……); if(lpEntry!=NULL) return DispatchCmdMsg(……lpEntry->pfn,……); } return FALSE; }
从代码中可以看出,OnCmdMsg各自调用的顺序刚好就是图1中所要求的顺序,这样也就实现了消息的拐弯流动,最后DispatchCmdMsg 函数是调用找到的消息处理函数处理消息。至此消息从出现到找到处理函数已经完成! 
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
2/2 首页 上一页 1 2 |