• <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>
            隨筆 - 224  文章 - 41  trackbacks - 0
            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            享受編程

            常用鏈接

            留言簿(11)

            隨筆分類(159)

            隨筆檔案(224)

            文章分類(2)

            文章檔案(4)

            經(jīng)典c++博客

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            原文地址:http://blog.csdn.net/wzyzb/archive/2009/03/05/3959564.aspx
            PreTranslateMessage是消息在送給TranslateMessage函數(shù)之前被調(diào)用的,絕大多數(shù)本窗口的消息都要通過(guò)這里,比較常用,當(dāng)需要在MFC之前處理某些消息時(shí),常常要在這里添加代碼. 
                  

                   MFC 消息控制流最具特色的地方是CWnd類的虛擬函數(shù)PreTranslateMessage(),通過(guò)重載這個(gè)函數(shù),可以改變MFC的消息控制流程,甚至可以作一個(gè)全新的控制流出來(lái)。只有穿過(guò)消息隊(duì)列的消息才受PreTranslateMessage()影響,采用SendMessage()或其他類似的方式向窗口直接發(fā)送的而不經(jīng)過(guò)消息隊(duì)列的消息根本不會(huì)理睬PreTranslateMessage()的存在。 

                   是否調(diào)用TranslateMessage()和DispatchMessage()是由一個(gè)名稱為PreTranslateMessage()函數(shù)的返回值決定的,如果該函數(shù)返回TRUE,則不會(huì)把該消息分發(fā)給窗口函數(shù)處理。

            傳給PreTranslateMessage()的消息是未經(jīng)翻譯過(guò)的消息,它沒(méi)有經(jīng)過(guò)TranslateMessage()處理。可以在該函數(shù)中使用(pMsg->wParam==VK_RETURN)來(lái)攔截回車鍵。wParam中存放的是鍵盤上字符的虛擬碼。

            PeekMessage和GetMessage的區(qū)別:

            GetMessage在沒(méi)有消息的時(shí)候等待消息,cpu當(dāng)然低

            PeekMessage沒(méi)有消息的時(shí)候立刻返回,所以cpu占用率高。

            因?yàn)橛螒虿荒芸縲indows消息驅(qū)動(dòng),所以要用PeekMessage();

                 PretranslateMessage 的實(shí)現(xiàn),不得不談到MFC消息循環(huán)的實(shí)現(xiàn)。MFC通過(guò)CWinApp類中的Pumpmessage函數(shù)實(shí)現(xiàn)消息循環(huán),但是實(shí)際的消息循環(huán)代碼位于 CWinThread中,CWinApp只是從CWinThread繼承過(guò)來(lái)。其簡(jiǎn)化后的代碼大概如下:
              BOOL CWinThread::PumpMessage()
              {
              _AFX_THREAD_STATE *pState = AfxGetThreadState();
              
              ::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL))
              
              if (!AfxPreTranslateMessage(&(pState->m_msgCur)))
              {
              ::TranslateMessage(&(pState->m_msgCur));
              ::DispatchMessage(&(pState->m_msgCur));
              }
              return TRUE;
              }
              可以看到,PumpMessage在實(shí)際的TranslateMessage和DispatchMessage發(fā)生之前會(huì)調(diào)用 AfxPreTranslateMessage,AfxPreTranslateMessage又會(huì)調(diào)用 CWnd::WalkPreTranslateTree(雖然也會(huì)調(diào)用其他函數(shù),但是這個(gè)最為關(guān)鍵),其代碼如下:
              BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
              {
              ASSERT(hWndStop == NULL || ::IsWindow(hWndStop));
              ASSERT(pMsg != NULL);
              
              // walk from the target window up to the hWndStop window checking
              // if any window wants to translate this message
              
              for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
              {
              CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
              if (pWnd != NULL)
              {
              // target window is a C window
              if (pWnd->PreTranslateMessage(pMsg))
              return TRUE; // trapped by target window (eg: accelerators)
              }
              
              // got to hWndStop window without interest
              if (hWnd == hWndStop)
              break;
              }
              return FALSE; // no special processing
              }
              
              可以看到,代碼還是很直接的。從接受到消息的窗口層層往上遍歷,并調(diào)用PretranslateMessage看是否返回TRUE,是則結(jié)束,否則繼續(xù)。
              這里有一個(gè)地方非常關(guān)鍵:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) 這一句代碼從當(dāng)前AfxModuleThreadState拿到Permanent句柄表,從而找到hWnd對(duì)應(yīng)的CWnd


            MFC 中PreTranslateMessage是GetMessage(...)函數(shù)的下一級(jí)操作,即GetMessage(...)從消息隊(duì)列中獲取消息后,交由PreTranslateMessage()處理,若其返回FALSE則再交給TranslateMessage和 DispatchMessage處理(進(jìn)入WindowProc);  
            如果用SendMessage,   則消息直接交到WindowProc處理,所以GetMessage不會(huì)取得SendMessage的消息,當(dāng)然PreTranslateMessage也就不會(huì)被調(diào)用。   [Page]
            如果用PostMessage,則消息進(jìn)入消息隊(duì)列,由GetMessage取得,PreTranslateMessage就有機(jī)會(huì)進(jìn)行處理。

            例子:
            按Enter,ESC按是不會(huì)退出了

            BOOL CComboBoxExDlg::PreTranslateMessage(MSG* pMsg)
            {
            if(WM_KEYDOWN == pMsg->message )
            {
            UINT nKey = (int) pMsg->wParam; 
            if( VK_RETURN == nKey || VK_ESCAPE == nKey )
            return TRUE ;
            }

            return CDialog::PreTranslateMessage(pMsg);
            }

            編輯框,如何響應(yīng)的這個(gè)回車的信息
            如果你的編輯框定義如下  
              CEdidt   m_cName;       //ID號(hào)為IDC_E_NAME  
               
              BOOL   CSecondDlg::PreTranslateMessage(MSG*   pMsg)    
              {  
              //   TODO:   Add   your   specialized   code   here   and/or   call   class  
               
                            if   (pMsg->message==WM_KEYDOWN)  
              {  
                      //CWnd   *p=GetDlgItem(IDC_E_NAME);  
              CWnd   *   hWnd=GetFocus();  
              //if(pMsg->wParam==13   &&   pMsg->hwnd==m_cName)  
              if(pMsg->wParam==13   &&   hWnd==&m_cName)  
              {  
              處理函數(shù)  
              return   TRUE;  
              }  
              else  
              {  
                                                                      處理函數(shù)  
              }  
              }  
              return   CDialog::PreTranslateMessage(pMsg);  
              }

            posted on 2010-01-18 09:22 漂漂 閱讀(2959) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 深入vc++
            91精品日韩人妻无码久久不卡| 伊人久久大香线蕉AV一区二区| 久久婷婷色综合一区二区| 91久久精品视频| 欧美亚洲另类久久综合| AAA级久久久精品无码片| 久久久久人妻精品一区| 久久国产精品成人影院| 99久久免费国产精品热| 久久精品国产精品亚洲精品| 精品久久久久久久| 国产叼嘿久久精品久久| 久久精品国产福利国产琪琪| 日韩精品无码久久一区二区三| 日本精品一区二区久久久| 亚洲日本久久久午夜精品| 久久久久久亚洲Av无码精品专口| 国产精品久久久久天天影视| 国产巨作麻豆欧美亚洲综合久久 | 国产亚洲色婷婷久久99精品91| 狠狠精品久久久无码中文字幕 | 色综合久久天天综合| 久久亚洲视频| 久久精品欧美日韩精品| 久久久久婷婷| 72种姿势欧美久久久久大黄蕉 | 国产精品欧美久久久天天影视 | 99久久免费只有精品国产| 久久天天日天天操综合伊人av| 亚洲午夜久久久久久噜噜噜| 好久久免费视频高清| 日日狠狠久久偷偷色综合免费| 亚洲精品无码久久一线| 国产免费福利体检区久久| 97精品依人久久久大香线蕉97| 亚洲一区二区三区日本久久九| 97精品依人久久久大香线蕉97 | 久久青青草原亚洲av无码app| 久久99国产一区二区三区| 久久久久亚洲AV无码专区体验| 久久久久噜噜噜亚洲熟女综合|