<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數據加載中……

    MFC的消息映射機制

    =================================================================================================
    MFC將消息分為以下三種類型:
    (1)標準消息:除WM_COMMAND之外,所有以WM_開頭的消息,從CWnd派生的類,都可以接收到這類消息。
    (2)命令消息:來自菜單、加速鍵或工具欄按鈕的消息。這類消息都以WM_COMMAND呈現。在MFC中,通過菜單項的標識(ID)來區分不同的命令消息;在SDK中,通過消息的wParam參數識別。從CCmdTarget派生的類,都可以接收到這類消息。
    (3)通告消息:由控件產生的消息,例如,按鈕的單擊,列表框的選擇等均產生此類消息,為的是向其父窗口(通常是對話框)通知事件的發生。這類消息也是以WM_COMMAND形式呈現。從CCmdTarget派生的類,都可以接收到這類消息。

    某個窗口產生一個消息,該消息中的第一個參數就是與這個窗口有關的句柄,由于VC++系統在后臺維護了一個句柄和指針的映射關系,因此就可以從這個句柄找到對應的指針,然后將指針傳遞給基類,消息循環的最終結果都會歸結為調用基類(窗口類的基類也就是CWnd類)中的WindowProc函數,下面詳細的分析了MFC對消息的處理過程:
    MFC對于各類消息都是先交由一個“Afx(即應用程序框架函數)”LRESULT CALLBACK AfxWndProc<for all CWnd's and derived classes>來處理;
    然后再調用LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, WPARAM wParam = 0, LPARAM lParam = 0)<Official way to send message to a CWnd>;
    然后再調用LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)<main WindowProc implementation>;
    然后再調用BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);在OnWndMsg函數中會針對不同的消息類型進行不同的處理,對于命令消息它會交由BOOL OnCommand(WPARAM wParam, LPARAM lParam)來處理;對于通告消息,會交由BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)來處理;需要說明的一點是不論是命令消息還是通告消息,最終都會調用OnCmdMsg函數。如果消息不是命令消息或通告消息,即為標準消息,則會最終到一個switch結構中去尋找,如果在OnWndMsg中未能響應消息,則交由默認的消息處理函數LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)<Default CWnd implementation>。
    在OnWndMsg函數中的case結構中有很多類似于這樣的語句:lResult = (this->*mmf.pfn_is)((LPTSTR)lParam);根據多態性,這里面的this指針往往都是指向基類的,例如CMainFrame或CXXXView類等的對象,這里面的mmf.pfn_is是一個指向函數的指針,因此執行這句話調用消息處理的入口就會遵循先到子類中查找是否存在這樣的消息處理函數,如果子類沒有,才會上溯到基類中去尋找。
    =================================================================================================
    自定義消息:#define UM_XXXX WM_USER+X;聲明消息響應函數原型afx_msg void OnXXXX();添加消息映射ON_MESSAGE(UM_XXXX,OnXXXX);編寫消息響應函數代碼;使用SendMessage或者PostMessage函數發送消息。

    GetMessage會等待消息處理完畢后再取出下一條消息;PeekMessage只會窺視一下即將取出的下一條消息,而不會做任何與消息處理有關的工作。

    CWnd::SendMessage會發送消息,并等待消息返回,在程序執行過程中使用該函數,就相當于把消息響應函數的函數體插放到當前程序體中;CWnd::PostMessage會發送消息,但是不會等待消息處理完成后才返回,這個函數會立刻返回,它只是在消息隊列的頭部放置了一個新的消息,至于這個消息多會兒被響應就是系統底層消息循環的事情了。
    =================================================================================================
    這里要提到的這個觀點太過于經典了,因此一定要好好領會,永遠不能忘記。

    MFC的消息相應是通過將產生的消息放置到一個消息隊列中,然后由系統不停的從隊列的頭部取出消息進行響應和執行,由于消息響應在一個時刻只能響應一個消息,而不能同時響應若干個消息,因此只有等待當前的消息處理完成后才能夠進行下一個消息的響應,因此如果我們希望在響應完一個消息之后(也就是在程序中表現為執行完一個消息響應函數的函數體之后)再去做另外一件工作,那就可以在當前的消息響應函數中發送一個消息,在這個發送出去的消息的響應函數中去做那些工作就可以了。而這個發送的消息可以是我們自定義的消息。
    =================================================================================================

    posted on 2008-02-23 19:14 so true 閱讀(521) 評論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 天堂在线免费观看| 国产免费福利体检区久久| 69视频免费观看l| 久久精品国产亚洲AV香蕉| 久久国产乱子精品免费女| 亚洲精品无码不卡在线播HE| caoporn国产精品免费| 久久久无码精品亚洲日韩软件| 国产免费久久久久久无码| 亚洲日韩精品射精日| 免费国产99久久久香蕉| 亚洲国产精品一区第二页 | 免费大片av手机看片高清| 国产男女猛烈无遮挡免费视频网站 | 亚洲国产精久久久久久久| 久草免费手机视频| 精品亚洲A∨无码一区二区三区| 98精品全国免费观看视频| 亚洲国产成人精品电影| 成人毛片免费观看视频大全| 黄色毛片免费网站| 国产亚洲无线码一区二区| 222www免费视频| 亚洲丶国产丶欧美一区二区三区| 国产青草视频免费观看97| 人人鲁免费播放视频人人香蕉| 国产成A人亚洲精V品无码性色| 日韩精品久久久久久免费| 中文字幕无码亚洲欧洲日韩| 免费一级毛片免费播放| 日本免费高清视频| 亚洲中文字幕无码mv| 亚洲综合区小说区激情区| 美丽姑娘免费观看在线观看中文版| 亚洲一区免费视频| 亚洲综合色视频在线观看| 最刺激黄a大片免费网站| 亚洲av无码专区青青草原| 国产成A人亚洲精V品无码| 免费毛片在线播放| 免费观看91视频|