您的位置:逆风者 VC++ 正文
 添加时间:2007-09-01 原文发表:2007-08-31 人气:89 来源:vckbase.com

本文章共5248字,分4页,当前第3页,快速翻页:
 


五、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 - 下一页>>
相关文章

PhotoShop插件开发之选区(Selection)
编写多文档应用程序
COM 组件设计与应用(五)——用 ATL 写第一
MFC程序员的WTL指南: 中文版序言
不重起Windows直接更改IP地址
类似于FlashGet的悬浮框的制作
毫秒定时器
C :使用 Visual C 2005 的现代语言特色
IP Messenger 详细分析
可设置单元格颜色的ClistCtrl类
定制调试诊断工具和实用程序——摆脱DLL“地
WMI 的一个实现
自绘按钮的实现
《系统飞狐》系列软件中的“系统监视器”开
定时显示远程计算机的桌面
一个实用的CToolBar扩展类CToolBarEx
简单实用的Xml解析类
SQL Server 索引结构及其使用(三)
图形显示特技算法
论程序设计方法

相关评论


本文章所属分类:首页 VC++

  热门关键字: