• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    分析與理解消息反射機制

    發布: 2007-7-14 21:11 | 作者: 佚名    | 來源: 網絡轉載     | 查看: 75次 | 進入軟件測試論壇討論

    領測軟件測試網 鄭力群

    前言:

      我曾寫過一篇文章對通知消息WM_NOTIFY進行分析,消息反射是MFC中對通知消息的處理方式,兩者之間關系十分緊密,因此,我寫了這篇文章,希望能夠描繪出通知消息的完整印象。

    消息反射的基礎知識

    1、消息反射解釋:
      父窗口將控制子窗口發給它的通知消息,首先反射回子窗口進行處理(即給控制子窗口一個機會,讓控制子窗口處理此消息),這樣通知消息就有機會能被子窗口自身進行處理。

    2、MFC中引入消息反射的原因:
      在Windows的消息處理中,控制子窗口的發給其父窗口的通知消息只能由其父窗口進行處理,這使得控制子窗口的自身能動性大大降低(你想,它連改變自己的背景色,處理一個自身滾動問題都要其父窗口來完成),為了解決這個問題,在MFC中引入了反射消息“Reflect Message”的概念,進行消息反射,可以使得控制子窗口能夠自行處理與自身相關的一些消息,增強了封裝性,從而提高了控制子窗口的可重用性。

    消息反射的處理流程(不考慮OLE控制)

    一、消息反射處理流程圖:
      1、父窗口收到控制子窗口發來的通知消息后,調用它的虛函數CWnd::OnNotify.
    CWnd::OnNotify()主體部分:
    {
    if (ReflectLastMsg(hWndCtrl, pResult)) //此時,hWndCtrl,為發送窗口,即子窗口的窗口句柄
    return TRUE; // 子窗口已處理了此消息
    AFX_NOTIFY notify;
    notify.pResult = pResult;
    notify.pNMHDR = pNMHDR;
    return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), &not;ify, NULL);
    }

      分析:首先,調用ReflectLastMsg(hCtrlChildWnd,...)給子窗口一個自身處理的機會,將消息反射給子窗口處理,函數返回TRUE,表明子窗口處理了此消息。反之,表示子窗口未處理此消息,此時,調用OnCmdMsg(...)由父窗口進行通常的處理。

      2、ReflectLastMsg中:
      主要是調用發送窗口的SendChildNotifyLastMsg(...)。

      3、SendChildNotifyLastMsg 中:
      調用發送窗口的虛函數OnChildNotify函數,進行處理。 如果沒有處理,則調用ReflectChildNotify(...)函數進行標準的反射消息的消息映射處理。


    二、消息處理

    方式1:
      由上述處理流程可以看出來,子窗口要想自身處理此消息,重載子控件窗口的OnChildNotify虛擬函數應該是很容易想到的方式。

      注意:MFC中對各個子控件窗口一般都已經重載了OnChildNotify函數,它對應調用類的虛函數進行處理,所以,你重載對應的虛函數即可,如下例:
    BOOL CStatusBarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,LRESULT* pResult)
    {
    if (message != WM_DRAWITEM) //對應不同的控制,會有不同的有特殊處理要求的消息。
    return CWnd::OnChildNotify(message, wParam, lParam, pResult);
    ...
    ...
    DrawItem((LPDRAWITEMSTRUCT)lParam);
    return TRUE;
    }
    virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
    void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
    {
    ASSERT(FALSE); // must override for self draw status bars
    }

      你重載CSTatusBarCtrl類的DrawItem虛擬函數,即可實現對反射消息WM_DRAWITEM的處理。

    方式2:
      從方式1可以看出,如果你不在被重載的OnChildNotify中對消息進行處理,函數會調用CWnd::OnChildNotify,它調用ReflectChildNotify函數進行標準的處理。
    1、增加反射消息的映射入口。
    2、增加對應的消息處理函數。
    注意:可以使用MFC的ClassWizard作上述動作,在ClassWizard中,可處理的反射消息以一個"="號以示區別。返回值為TRUE,表示控件窗口已處理此反射消息,為FALSE,表示控件子窗口未處理此反射消息。

    結語:

      消息反射不是很難的概念。它僅出現在MFC中;它的用意是方便控制子窗口的重用;對某些通知消息你可以重載對應的虛函數(WM_DRAWITEM...)進行處理;對其它你可以使用標準的消息反射映射進行處理。限于篇幅,一些細節問題,請閱讀MFC中對應的源代碼。  

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>