• <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久久99精品免视看动漫| 国产麻豆精品久久一二三| 国产 亚洲 欧美 另类 久久| 久久久久亚洲AV成人网人人软件| 99热精品久久只有精品| 狠狠色综合网站久久久久久久| 久久精品国产AV一区二区三区| 伊人久久无码中文字幕| 欧美色综合久久久久久| 欧美亚洲国产精品久久蜜芽 | 狠狠久久综合伊人不卡| 亚洲欧美国产精品专区久久| 久久国产精品-国产精品| 无码八A片人妻少妇久久| 久久久久无码精品| 亚洲∧v久久久无码精品| 国产aⅴ激情无码久久| 亚洲国产精品一区二区久久| 99国产欧美久久久精品蜜芽| 久久99精品久久久久子伦| 久久久精品久久久久影院| 午夜精品久久久久久影视777| 99久久久精品免费观看国产| 亚洲精品蜜桃久久久久久| 欧美午夜精品久久久久久浪潮| 91久久精品91久久性色| 色婷婷久久综合中文久久一本| 色偷偷久久一区二区三区| 色欲综合久久中文字幕网| 一本久久综合亚洲鲁鲁五月天| 久久er热视频在这里精品| 996久久国产精品线观看| 亚洲国产欧洲综合997久久| 尹人香蕉久久99天天拍| 久久无码一区二区三区少妇 | 色婷婷狠狠久久综合五月| 国产高潮久久免费观看| 国产一区二区三区久久精品| 成人综合伊人五月婷久久| 国产一区二区三区久久| 久久久久综合网久久|