<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++

    主站蜘蛛池模板: 亚洲av无码专区在线电影| 精品亚洲成在人线AV无码| 黄色免费网址在线观看| 成人性生交视频免费观看| 亚洲人成网网址在线看| 日本免费网址大全在线观看 | 在线观看免费视频一区| 国产亚洲精久久久久久无码77777| 一级毛片视频免费| 久久久久无码专区亚洲av| 国产成人精品免费大全| 久久精品国产69国产精品亚洲| 日本免费久久久久久久网站| 亚洲国产精品无码久久久不卡| 久久青草免费91线频观看不卡| 亚洲成年人免费网站| 69成人免费视频无码专区| 亚洲AV无码片一区二区三区| 国产无遮挡又黄又爽免费视频| 在线播放免费人成视频网站| 亚洲精品成人无限看| 日本在线高清免费爱做网站| 亚洲av无码有乱码在线观看| 亚洲午夜爱爱香蕉片| 日本免费人成视频在线观看| 亚洲中文字幕日本无线码| yy6080久久亚洲精品| 男人j进入女人j内部免费网站| 亚洲欧洲日产国码在线观看| 日韩a级毛片免费视频| 久久精品成人免费国产片小草| 亚洲最大的成网4438| 午夜免费不卡毛片完整版| 成人免费ā片在线观看| 2022年亚洲午夜一区二区福利| 免费无码黄动漫在线观看| 国产免费福利体检区久久| 中文字幕亚洲免费无线观看日本| 国产精品免费电影| 久草福利资源网站免费| 亚洲精品第一国产综合亚AV|