• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-161  評論-223  文章-30  trackbacks-0

               MFC將windows消息系統(tǒng)進(jìn)行了高度的抽象和封裝,其根本原理是運(yùn)用C++的高級特性并結(jié)合一定的設(shè)計模式(如工廠模式,模板方法等)來實現(xiàn)的。一般的windows消息(WM_XXX),則一定是由派生類流向基類,沒有旁流的可能。如果是命令消息(WM_COMMAND),那就有比較奇特的路線了。下面就針對多文檔/單文檔(Document-View)、對話框兩種應(yīng)用程序比較討論WM_COMMAND消息的傳遞處理過程。討論前首先得明確命令消息的來源,命令消息一般是用戶選擇某個菜單項,或一個加速鍵被翻譯,或一個子控件發(fā)送一個通知消息給它的父窗口時產(chǎn)生的。對一個菜單而言,消息接收者是Frame窗口或擁有它的對話框;對一個工具欄而言,消息接收者是它的父窗口。兩種應(yīng)用程序命令消息處理流程如下圖所示。                   

               從上圖可知,文檔視圖型的處理路線是先向下再向上,而對話框型的路線是一直向上,消息接收者只有一個,而處理者次序有多個,每個處理者內(nèi)部首先都是調(diào)用根基類CCmdTarget的OnCmdMsg虛函數(shù),在這個函數(shù)內(nèi)逐級向基類遍歷消息映射表,根據(jù)命令I(lǐng)D和通知碼找到對應(yīng)的消息映射結(jié)構(gòu)體AFX_MSGMAP_ENTRY,如果找到再處理這個命令消息,否則返回FALSE,退回到this對象所在的OnCmdMsg函數(shù)進(jìn)行下一步處理。如果到最后一層都沒有找到對應(yīng)命令的消息映射,則返回到系統(tǒng)的默認(rèn)處理DefWindowProc。再綜合考慮下,如果一個對話框接收到了一個命令消息例如是點(diǎn)擊它的子控件工具欄某個按鈕發(fā)出的,而這個對話框類沒有添加相應(yīng)的ON_COMMAND映射,就會進(jìn)入到它的父窗口類OnCmdMsg函數(shù)進(jìn)行處理,如果這個父窗口正好是Frame窗口,那么命令消息的處理流程就由上圖右邊轉(zhuǎn)到左邊了。而最終命令消息能否得處理,就看上圖5種對象(Frame、View、Document、Dialog、App、Thread)是否添加了對應(yīng)的ON_COMMAND映射。
               
               到此為止,我們已經(jīng)明確了WM_COMMAND消息的處理流程,但是發(fā)現(xiàn)最終處理卻是由收到消息的窗口傳遞的,不是消息通知者自己處理的,有的時候為了提高代碼的封裝性,可能需要自己處理這些命令比較方便,比如有一個工具欄CPlayToolBar子類從CToolBar繼承,有播放、暫停、停止3個按鈕,它的父窗口是CPlayDialog對話框。按照常規(guī),這3個按鈕命令事件的處理一般是在CPlayDialog類中3個ON_COMMAND映射宏和處理函數(shù)的,但如果在CPlayToolBar類中添加3個ON_COMMAND映射宏和處理函數(shù),是得不到處理的,其原因在于對話框型的路線是一直向上,再者M(jìn)FC中沒有對應(yīng)的命令反射ON_COMMAND_REFLECT這個宏。為了能使CPlayToolBar類自己處理這3個按鈕命令事件,就需要從CPlayDialog類中轉(zhuǎn)移路線,使之流向其子窗口工具欄,這樣CPlayToolbar 類就得到了自己處理的機(jī)會。具體操作是重載CPlayToolBar和CPlayDialog的OnCommand虛函數(shù),  CPlayDialog代碼如下所示:
             1  BOOL   CPlayDialog::OnCommand(WPARAM wParam, LPARAM lParam)
             
            2  {
             
            3         if (lParam==(LPARAM)m_playtoolbar.m_hWnd)
             
            4        {
             
            5              m_playtoolbar.OnCommand(wParam,lParam);   //m_playtoolbar為CPlayToolBar對象,注意使OnCommand成為公有成員
             6        }

             
            7       else
             
            8       {
             
            9            return   CDialog::OnCommand(wParam, lParam);
            10       }

            11   }
               CPlayToolBar類代碼如下所示
             1    BEGIN_MESSAGE_MAP(CPlayToolBar, CToolBar)
             
            2         ON_COMMAND(ID_PLAY,  Play)
             
            3         ON_COMMAND(ID_PAUSE,  Pause)
             
            4         ON_COMMAND(ID_STOP,  Stop)
             5    END_MESSAGE_MAP()
             
            6
             7    void   CPlayToolBar::Play()
             
            8    {
             
            9    }

            10   void   CPlayToolBar::Pause()
            11   {
            12   }

            13   void   CPlayToolBar::Stop()
            14   
            15   }
                現(xiàn)在,3個按鈕命令事件能在CPlayToolBar類中獨(dú)立處理了,這樣一來就提高了代碼的封裝性,簡化了父窗口CPlayDialog類的處理。
            posted on 2009-12-19 21:29 春秋十二月 閱讀(6091) 評論(1)  編輯 收藏 引用 所屬分類: C/C++
            四虎国产精品成人免费久久| 伊人久久亚洲综合影院| 久久精品国产久精国产思思| 婷婷综合久久中文字幕蜜桃三电影| 久久香综合精品久久伊人| 久久99精品久久久大学生| 国产午夜免费高清久久影院| 99久久伊人精品综合观看| 久久无码AV一区二区三区| av无码久久久久不卡免费网站| 色综合久久精品中文字幕首页| 亚洲精品第一综合99久久 | 亚洲一本综合久久| 婷婷久久综合九色综合九七| 欧美一区二区三区久久综| 久久久久国产精品三级网| A级毛片无码久久精品免费| 国产精品美女久久久免费| 99久久精品免费看国产一区二区三区 | 久久久久国产精品嫩草影院| 色综合合久久天天综合绕视看 | 久久精品视频免费| 久久精品一本到99热免费| 精品久久人人妻人人做精品 | 久久国产热这里只有精品| 久久精品99久久香蕉国产色戒| 婷婷久久综合| 老司机午夜网站国内精品久久久久久久久| 久久精品国产亚洲AV久| 久久精品国产72国产精福利| 国产精品视频久久久| 久久免费的精品国产V∧| 久久久久久综合网天天| 亚洲国产视频久久| 欧美日韩久久中文字幕| 久久久久亚洲精品日久生情| 99久久香蕉国产线看观香| 国产精品乱码久久久久久软件| 免费精品久久久久久中文字幕| 久久免费视频一区| 久久午夜综合久久|