• <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
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            享受編程

            常用鏈接

            留言簿(11)

            隨筆分類(159)

            隨筆檔案(224)

            文章分類(2)

            文章檔案(4)

            經典c++博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

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

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

                   是否調用TranslateMessage()和DispatchMessage()是由一個名稱為PreTranslateMessage()函數的返回值決定的,如果該函數返回TRUE,則不會把該消息分發給窗口函數處理。

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

            PeekMessage和GetMessage的區別:

            GetMessage在沒有消息的時候等待消息,cpu當然低

            PeekMessage沒有消息的時候立刻返回,所以cpu占用率高。

            因為游戲不能靠windows消息驅動,所以要用PeekMessage();

                 PretranslateMessage 的實現,不得不談到MFC消息循環的實現。MFC通過CWinApp類中的Pumpmessage函數實現消息循環,但是實際的消息循環代碼位于 CWinThread中,CWinApp只是從CWinThread繼承過來。其簡化后的代碼大概如下:
              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在實際的TranslateMessage和DispatchMessage發生之前會調用 AfxPreTranslateMessage,AfxPreTranslateMessage又會調用 CWnd::WalkPreTranslateTree(雖然也會調用其他函數,但是這個最為關鍵),其代碼如下:
              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
              }
              
              可以看到,代碼還是很直接的。從接受到消息的窗口層層往上遍歷,并調用PretranslateMessage看是否返回TRUE,是則結束,否則繼續。
              這里有一個地方非常關鍵:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) 這一句代碼從當前AfxModuleThreadState拿到Permanent句柄表,從而找到hWnd對應的CWnd


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

            例子:
            按Enter,ESC按是不會退出了

            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);
            }

            編輯框,如何響應的這個回車的信息
            如果你的編輯框定義如下  
              CEdidt   m_cName;       //ID號為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)  
              {  
              處理函數  
              return   TRUE;  
              }  
              else  
              {  
                                                                      處理函數  
              }  
              }  
              return   CDialog::PreTranslateMessage(pMsg);  
              }

            posted on 2010-01-18 09:22 漂漂 閱讀(2959) 評論(0)  編輯 收藏 引用 所屬分類: 深入vc++
            99久久人人爽亚洲精品美女| 国产69精品久久久久APP下载| www.久久热.com| 久久国产视屏| 婷婷久久久亚洲欧洲日产国码AV| 国产精品久久久久久久久鸭| 久久综合伊人77777| 国产高潮国产高潮久久久| 久久久久亚洲av成人无码电影| 亚洲熟妇无码另类久久久| 精品无码久久久久久久动漫| 热re99久久6国产精品免费| 无夜精品久久久久久| 久久免费精品视频| 色8久久人人97超碰香蕉987| 免费精品久久久久久中文字幕| 久久精品国产亚洲av高清漫画| 久久久久18| 亚洲综合婷婷久久| 久久久久久亚洲精品成人| 久久久国产99久久国产一| 国产巨作麻豆欧美亚洲综合久久| 久久久无码一区二区三区| 色综合久久夜色精品国产| 国产亚洲成人久久| 青青热久久综合网伊人| 欧美喷潮久久久XXXXx| 久久久久亚洲AV成人网人人网站| 久久影院亚洲一区| 久久久久国产一区二区三区| 久久国产精品久久国产精品| 欧美大香线蕉线伊人久久| 777午夜精品久久av蜜臀 | www久久久天天com| 久久久久久久久波多野高潮| 亚洲午夜福利精品久久| 欧美精品丝袜久久久中文字幕| 久久久久国产亚洲AV麻豆| 久久91精品综合国产首页| 国产精品成人99久久久久91gav| 久久九九青青国产精品|