五、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;
} 本文章更多内容:<<上一页 - 1 - 2 - 3 - 4 - 下一页>> |