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

            平凡的天才

            目的是為人類造福
            posts - 20, comments - 41, trackbacks - 0, articles - 6
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            MFC消息詳解

            Posted on 2007-03-09 11:22 平凡的天才 閱讀(7519) 評(píng)論(0)  編輯 收藏 引用

            轉(zhuǎn)載自http://blog.csdn.net/Image_Graphics/archive/2006/11/22/1405436.aspx


            1. 怎樣使用MFC發(fā)送一個(gè)消息用MFC發(fā)送一個(gè)消息的方法是,
            ????首先,應(yīng)獲取接收消息的CWnd類對(duì)象的指針;
            ????然后,調(diào)用CWnd的成員函數(shù)SendMessage( )。
            ????????LRESULT Res=pWnd->SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
            ????????pWnd指針指向目標(biāo)CWnd類對(duì)象。變量Msg是消息,wParam和lParam變量包含消息的參數(shù),如鼠標(biāo)單擊哪里或選擇了什么菜單項(xiàng)。目標(biāo)窗口返回的消息結(jié)果放在變量Res中。
            ????????發(fā)送消息到一個(gè)沒有CWnd類對(duì)象的窗口,可以用下列目標(biāo)窗口的句柄直接調(diào)用Windows API:
            ????????LRESULT Res=::SendMessage(HWND hWnd, UINT Msg,? WPARAM wParam, LPARAM lParam);
            ????????這里的hWnd是目標(biāo)窗口的句柄。
            2. 怎樣用MFC寄送一個(gè)消息
            ????用MFC寄送一個(gè)消息與發(fā)送一個(gè)消息幾乎相同,但寄送時(shí)用PostMessage( ) ,而不是用SendMessage( );返回值Res也不一樣,Res不是一個(gè)由目標(biāo)窗口返回的值,而是一個(gè)布爾值,用來表示消息是否成功地放到消息隊(duì)列中。
            3. 檢索一個(gè)寄送消息
            ????正常情況下,一旦消息被寄送后,應(yīng)用程序在后臺(tái)發(fā)送它。但是在特殊情況下,需要你自己去刪除一個(gè)消息,例如想在應(yīng)用程序接收到某種消息之前停止應(yīng)用程序。有兩種方法可以從應(yīng)用程序消息隊(duì)列中刪除一個(gè)消息,但這兩種方法都沒有涉及MFC。
            ■ 第一種方法:在不干擾任何事情之下窺視消息隊(duì)列,看看一個(gè)消息是否在那里。
            ????BOOL res=::PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ) ;
            ■ 第二種方法:實(shí)際上是等待,一直等到一個(gè)新的消息到達(dá)隊(duì)列為止,然后刪除并返回該消息。
            ????BOOL res=::GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
            ????在這兩種方法中,變量hWnd指定要截獲消息的窗口,如果該變量設(shè)為NULL,所有窗口消息將被截獲。wMsgFilterMin和wMsgFilterMax變量與SendMessage( )中的變量Msg相對(duì)應(yīng),指定查看消息的范圍。如果用"0,0",則所有的消息都將被截獲。如果用WM_KEYFIRST,WM_KEYLAST或WM_MOUSEFIRST,WM_MOUSELAST,則所有鍵盤或鼠標(biāo)的消息將被截獲。wRemoveMsg變量指定PeekMessage( )是否應(yīng)該真正地從隊(duì)列中刪除該消息。(GetMessage( )總是刪除消息)。該變量可以取兩個(gè)值:
            ????■ PM_REMOVE,PeekMessage( )將刪除消息。
            ????■ PM_NOREMOVE,PeekMessage( )將把消息留在隊(duì)列里,并返回它的一個(gè)拷貝。
            ????當(dāng)然,如果把消息留在消息隊(duì)列中,然后再次調(diào)用PeekMessage( )查看相同類型的消息,則將返回完全相同的消息。
            ????lpMsg變量是一個(gè)指向MSG結(jié)構(gòu)的指針,MSG包含檢索到的消息。
            ????typedef struct tagMSG {
            ????????????????????????HWND hwnd; // window handle message is intended for
            ????????????????????????UINT message;
            ????????????????????????WPARAM wParam;
            ????????????????????????LPARAM lParam;
            ????????????????????????DWORD time; // the time the message was put in the queue
            ????????????????????????POINT pt; // the location of the mouse cursor when the
            ?????????????????????????????????????? // message was put in the queue
            ????????????????????????} MSG;
            4. MFC怎樣接收一個(gè)寄送的消息
            ??? MFC處理一個(gè)寄送和發(fā)送消息的唯一明顯不同是寄送的消息要在應(yīng)用程序的消息隊(duì)列中花費(fèi)一些時(shí)間。在消息泵(message pump)彈出它之前,它要一直在隊(duì)列中。
            ??? 消息泵
            ??? MFC應(yīng)用程序中的消息泵在CWinApp的成員函數(shù)Run()中。應(yīng)用程序開始運(yùn)行時(shí),Run()就被調(diào)用,Run()把時(shí)間分割成兩部分。一部分用來執(zhí)行后臺(tái)處理,如取消臨時(shí)CWnd對(duì)象;另一部分用來檢查消息隊(duì)列。當(dāng)一個(gè)新的消息進(jìn)來時(shí),Run()抽取它—即用GetMessage( )從隊(duì)列中取出該消息,運(yùn)行兩個(gè)消息翻譯函數(shù),然后用DispatchMessage( )函數(shù)調(diào)用該消息預(yù)期的目標(biāo)窗口進(jìn)程。
            ??? 消息泵調(diào)用的兩個(gè)翻譯函數(shù)是PreTranslateMessage( )和::TranslateMessage( )。目標(biāo)窗口的MFC類可調(diào)用reTranslateMessage在發(fā)送消息給它之前進(jìn)行消息翻譯,例如,CFrameWnd用PreTranslateMessage( )將加速鍵(如,Ctrl+S存儲(chǔ)文件)轉(zhuǎn)換為命令消息。翻譯前的消息通常被處理掉,而翻譯后的消息(如果有的話)將被重新寄送到隊(duì)列里。::TranslateMessage是一個(gè)窗口函數(shù),將原始鍵碼轉(zhuǎn)換為鍵字符。消息一旦被DispatchMessage()發(fā)送,MFC處理它就像處理SendMessage()發(fā)送的消息一樣。
            5. MFC怎樣處理一個(gè)接收到的消息
            ??? 處理接收到的消息的目的非常簡(jiǎn)單:將消息指向一個(gè)函數(shù),該函數(shù)通過消息中的消息標(biāo)識(shí)符處理它。非MFC窗口用簡(jiǎn)單的case語句來實(shí)現(xiàn)該目標(biāo),每個(gè)case語句執(zhí)行一些函數(shù),或調(diào)用其他一些函數(shù)。
            ??? MainWndProc(HWND hWnd, UINT message, W PARAM wParam,LPARAM lParam)
            ??? {
            ??????? switch(message)
            ??????? {
            ??????? case WM_CREATE:
            ??????????? : : :
            ??????? break;
            ??????? case WM_PAINT:
            ??????????? : : :
            ??????? break;
            ??????? default:
            ??????? return(DefWindowProc(hWnd,message,wParam,lParam));
            ??????? }
            ??????? return(NULL);
            ??? }
            ??? 任何遺漏的消息將被傳輸?shù)揭粋€(gè)默認(rèn)的消息處理函數(shù),但是,case語句不能很好地適應(yīng)C++和封裝技術(shù)。在C++環(huán)境中,要求消息被一個(gè)專門處理該類型消息的類的成員函數(shù)處理。因此,MFC不采用case語句,而采用更加復(fù)雜和回旋的方法。但它允許用私有類處理消息,而只需做下面三件事情:
            ??? ■ 從將要接收消息的CWnd類對(duì)象派生類(對(duì)于命令消息是CCmdTarget)。
            ??? ■ 在派生類中寫一個(gè)處理消息的成員函數(shù)。
            ??? ■ 在類中定義一個(gè)查找表(叫做消息映像),該表具有成員函數(shù)的條目和它要處理的消息的標(biāo)識(shí)符。
            ??? 然后,MFC依次調(diào)用下面的函數(shù),指引輸入消息到處理函數(shù)。
            ??? 1) AfxWndProc( )接收消息,尋找消息所屬的CWnd對(duì)象,然后調(diào)用AfxCallWndProc( )。
            ??? 2) AfxCallWndProc( )存儲(chǔ)消息(消息標(biāo)識(shí)符和參數(shù))供未來參考,然后調(diào)用WindowProc( )。
            ??? 3) WindowProc( ) 發(fā)送消息給OnWndMsg( ) ,然后,如果消息未被處理,則發(fā)送給DefWindowproc( )。
            ??? 4) OnWndMsg( )要么為WM_COMMAND消息調(diào)用OnCommand( ),要么為WM_NOTIFY消息調(diào)用OnNotify( )。任何被遺漏的消息都將是一個(gè)窗口消息。OnWndMsg( )搜索類的消息映像,以找到一個(gè)能處理任何窗口消息的處理函數(shù)。如果OnWndMsg( )不能找到這樣的處理函數(shù),則把消息返回到WindowProc( ),由它將消息發(fā)送給DefWindowProc( )。
            ??? 5) OnCommand()查看這是不是一個(gè)控件通知(lParam不是NULL);如果它是,OnCommand( )就試圖將消息映射到制造通知的控件;如果它不是一個(gè)控件通知,或者控件拒絕映射的消息,OnCommand( )就調(diào)用OnCmdMsg( )。
            ??? 6) OnNotify( )也試圖將消息映射到制造通知的控件;如果映射不成功, OnNotify( )就調(diào)用相同的OnCmdMsg( )函數(shù)。
            ??? 7) 根據(jù)接收消息的類,OnCmdMsg( )將在一個(gè)稱為命令傳遞(Command Routing)的過程中潛在地傳遞命令消息和控件通知。例如,如果擁有該窗口的類是一個(gè)框架類,則命令和通知消息也被傳遞到視圖和文檔類,并為該類尋找一個(gè)消息處理函數(shù)。
            為什么要消息映像?
            ??? 這畢竟是C++語言;為什么OnWndMsg( )不為每個(gè)窗口消息調(diào)用一個(gè)預(yù)定義的虛擬函數(shù)?因?yàn)樗糃PU。若是那樣,當(dāng)掃描一個(gè)消息映像以加速該過程時(shí),OnWndMsg( )可能會(huì)做出意想不到的事情,并陷入?yún)R編器。注意通過重載WindowProc( )、OnWndMsg( )、OnCommand( )、OnNotify( ) 或OnCmdMsg( )可以修改這一過程。重載OnWndMsg( )可以在窗口消息被排序之前插入該過程。重載OnCommand( )或OnNotify( )可以在消息被反射之前插入該過程。


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            亚洲av日韩精品久久久久久a| 久久99精品久久久久久齐齐| 亚洲欧洲中文日韩久久AV乱码| 久久免费看黄a级毛片| 国产精品久久久久久久app | 国内精品伊人久久久久AV影院| 久久er热视频在这里精品| 中文字幕亚洲综合久久菠萝蜜| 久久这里只有精品首页| 精品久久久久久国产潘金莲| 草草久久久无码国产专区| 99999久久久久久亚洲| 一本一本久久a久久综合精品蜜桃| 精品一久久香蕉国产线看播放| 亚洲人成网站999久久久综合| 亚洲精品无码专区久久久 | 午夜不卡久久精品无码免费| 伊人久久免费视频| 久久国产高清字幕中文| 日韩欧美亚洲综合久久| 国产精品无码久久四虎| 狠狠久久亚洲欧美专区 | 狠狠色丁香久久婷婷综合_中| 久久综合丝袜日本网| 久久综合九色综合网站| 亚洲va久久久噜噜噜久久狠狠 | 波多野结衣久久精品| 91精品久久久久久无码| 久久精品a亚洲国产v高清不卡| 精品久久无码中文字幕| 久久精品极品盛宴观看| 久久精品国产亚洲av麻豆图片 | 无码人妻久久一区二区三区蜜桃| 国产欧美一区二区久久| 日韩精品久久久久久免费| 天天影视色香欲综合久久| 精品久久久久久国产免费了| 国产美女久久精品香蕉69| 99久久99久久久精品齐齐| 中文精品久久久久人妻不卡| 亚洲中文字幕无码一久久区 |