<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 閱讀(526) 評論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 亚洲国产aⅴ综合网| 亚洲AV无码AV日韩AV网站| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 亚洲欧洲国产精品久久| 亚洲桃色AV无码| 免费一级特黄特色大片在线| 无码专区永久免费AV网站| 国产拍拍拍无码视频免费| 一级午夜a毛片免费视频| 亚洲av成人一区二区三区在线播放| 亚洲视频免费一区| 亚洲精品无码MV在线观看| 免费一级毛片正在播放| 免费a在线观看播放| 永久黄网站色视频免费| 精品国产免费人成电影在线观看 | 拨牐拨牐x8免费| 24小时免费看片| 免费无码又爽又刺激高潮视频| 91国内免费在线视频| 午夜亚洲乱码伦小说区69堂| 亚洲AV无码一区二区三区网址| 亚洲一日韩欧美中文字幕在线| 亚洲国产成人精品青青草原| 亚洲经典在线中文字幕| 老汉色老汉首页a亚洲| 亚洲午夜免费视频| 久久精品国产亚洲AV网站| 中文字幕精品亚洲无线码二区| 免费一区二区三区四区五区| 俄罗斯极品美女毛片免费播放| 亚洲国产人成精品| 亚洲第一视频在线观看免费| 亚洲精品视频免费观看| 亚洲日韩中文在线精品第一| 亚洲av无码乱码在线观看野外| 亚洲国产一区二区视频网站| 国产亚洲精品无码拍拍拍色欲 | 久久一区二区免费播放| 中文字幕在线免费播放| 鲁丝片一区二区三区免费|