青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

面對現實,超越自己
逆水行舟,不進則退
posts - 269,comments - 32,trackbacks - 0

PreTranslateMessage作用和使用方法

         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繼承過來。其簡化后的代碼大概如下: 

 1   BOOL CWinThread::PumpMessage() 
 2   { 
 3   _AFX_THREAD_STATE *pState = AfxGetThreadState(); 
 4    
 5   ::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL)) 
 6    
 7   if (!AfxPreTranslateMessage(&(pState->m_msgCur))) 
 8   { 
 9   ::TranslateMessage(&(pState->m_msgCur)); 
10   ::DispatchMessage(&(pState->m_msgCur)); 
11   } 
12   return TRUE; 
13   }
      

      可以看到,PumpMessage在實際的TranslateMessageDispatchMessage發生之前會調用AfxPreTranslateMessageAfxPreTranslateMessage又會調用CWnd::WalkPreTranslateTree(雖然也會調用其他函數,但是這個最為關鍵),其代碼如下:

 1 BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg) 
 2   { 
 3   ASSERT(hWndStop == NULL || ::IsWindow(hWndStop)); 
 4   ASSERT(pMsg != NULL); 
 5    
 6   // walk from the target window up to the hWndStop window checking 
 7   // if any window wants to translate this message 
 8    
 9   for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) 
10   { 
11   CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); 
12   if (pWnd != NULL) 
13   { 
14   // target window is a C window 
15   if (pWnd->PreTranslateMessage(pMsg)) 
16   return TRUE; // trapped by target window (eg: accelerators) 
17   } 
18    
19   // got to hWndStop window without interest 
20   if (hWnd == hWndStop) 
21   break
22   } 
23   return FALSE; // no special processing 
24   } 
    

可以看到,代碼還是很直接的。從接受到消息的窗口層層往上遍歷,并調用PretranslateMessage看是否返回TRUE,是則結束,否則繼續。
  這里有一個地方非常關鍵:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) 這一句代碼從當前AfxModuleThreadState拿到Permanent句柄表,從而找到hWnd對應的CWnd MFCPreTranslateMessageGetMessage(...)函數的下一級操作,即GetMessage(...)從消息隊列中獲取消息后,交由PreTranslateMessage()處理,若其返回FALSE則再交給TranslateMessageDispatchMessage處理(進入WindowProc);  
如果用SendMessage,   則消息直接交到WindowProc處理,所以GetMessage不會取得SendMessage的消息,當然PreTranslateMessage也就不會被調用。   [Page]
如果用PostMessage,則消息進入消息隊列,由GetMessage取得,PreTranslateMessage就有機會進行處理。


windows
消息處理機制是這樣的:  
      
首先系統(也就是windows)把來自硬件(鼠標,鍵盤等消息)和來自應用程序的消息 放到一個系統消息隊列中去而應用程序需要有自己的消息隊列,也就是線程消息隊列,每一個線程有自己的消息隊列,對于多線程的應用程序就有和線程數目相等的線程消息隊列.  
  windows
消息隊列把得到的消息發送到線程消息隊列,線程消息隊列每次取出一條消息發送到指定窗口,不斷循環直到程序退出實現的.這個循環就是靠消息環(while(GetMessage()) TranslateMessage();DispatchMessage();.GetMessage()只是從線程消息中取出一條消息,TranslateMessage()virtue key消息轉化成character消息,如VK_F1會轉化成WM_HELP,DispatchMessage  則把取出的消息發送到目的窗口.如果收到WM_CLOSE消息則結束循環,發送postqiutmessage(0),處理WM_DESTROY毀窗口!

 while (GetMessage(&msg, NULL, 0, 0))          //C++ code
 {  
        TranslateMessage(&msg);
        DispatchMessage(&msg);
 }

 win32 程序中,關于消息有兩種傳遞方式:

1.      MFC 消息, MFC 會把所有的消息一條條放到一個 AFX_MSGMAP_ENTRY 結構中,形成一個數組,該數組存放了所有的消息和與

它們相關的參數。也可以說是放到消息隊列里去。

2.      采用 SendMessage() 或其他類似的方式向窗口直接發送的而不經過消息隊列的消息。


這兩種方式中只有第一種(穿過消息隊列的消息)才受 PreTranslateMessage() 影響,

第二種消息并不會理睬 PreTranslateMessage() 的存在。

1)      是否調用 TranslateMessage() 和 DispatchMessage() 是由一個名稱為 PreTranslateMessage() 函數的返回值決定的,如果該函數返回

 TRUE ,則不會把該消息分發給窗口函數處理。

2)      傳給 PreTranslateMessage() 的消息是未經翻譯過的消息,它沒有經過 TranslateMessage() 處理。可以在該函數中使用 

(pMsg->wParam==VK_RETURN) 來攔截回車鍵。

3)      在 WindowProc 里不能處理 WM_Char 消息。( WindowProc 函數見 MFC 消息響應機制一文)

4)      SetWindowText 會發送 WM_Char 給窗口。

5)      PeekMessage 和 GetMessage 的區別:

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

7)      PeekMessage 沒有消息的時候立刻返回,所以 cpu 占用率高。因為游戲不能靠 windows 消息驅動,所以要用 PeekMessage();


另一篇文章中:

            在一個 WIN32 程序中, WINDOWS 會將消息傳遞給相應的窗口。但是消息不是立即就被傳遞給相應的窗口,而是會從整個程序最頂層

的窗口傳遞到下一級窗 口,再傳遞到下一級窗口,直到傳遞給目標窗口。在整個過程中,有些消息,在某些特定的情況下,無法默認傳遞到目

標窗口的。比如用戶在 EDIT 控件中按下回 車鍵, CANCEL 鍵等,如果 EDIT 窗口之前有對話框窗口,對話框會默認處理回車消息(即響應 

ONOK 函數,然后關閉對話框),然后退出消息傳遞。所以 EDIT 會收不到。要解決這個問題,可以在 EDIT 窗口之前所有的對話框中重載 

PreTranslateMessage 函數,然后在函數內加上:

if (pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)     // 如果消息類型為WM_KEYDOWN 并且用戶按下的是回車 
  return FALSE;    // 不翻譯消息,直接將消息傳遞下去。具體可查 MSDN 。注意,這里返回值不能為TRUE , TRUE 的意思是翻譯消息后退出消

息傳遞,如此一來雖然也能避開對話框默認處理,但是會退出消息傳遞,這樣 EDIT 控件照樣得不到消息。

如此,就可避開對話框默認處理,將消息傳遞下去。注意:只有對話框才會默認處理按下回車,CANCEL 消息,其他控件窗口則不會,所以在其

他窗口中不必重載 PreTranslateMessage 函數,當然如果重載了也不會錯。


附:關于 PreTranslateMessage() 函數的小程序示例:

  1 BOOL CSearchuserDlg::PreTranslateMessage(MSG* pMsg) 
  3 {
  5      if (pMsg->message==WM_KEYDOWN)  // 判斷是否有按鍵按下 
  7      { 
  9            switch (pMsg->wParam) 
 11            { 
 13            case VK_DOWN:     // 表示是方向鍵中的向下的鍵
 15                 //add handle code here
 17                 break ;
 19            case VK_UP:      // 表示是方向鍵中的向上的鍵
 21                 //add handle code here
 23                 break ;
 25            default :
 27                 break ;
 29            }
 31      }
 33 } 
 36 
 37 BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
 38 {
 39      // TODO: Add your specialized code here and/or call the base class 
 41      // 按鍵相應
 42      if (pMsg->message == WM_KEYDOWN)
 43      {
 44            if (pMsg->wParam == VK_DOWN)
 45            {
 46                 // 向下鍵按下
 47            }
 48            else if (pMsg->wParam == VK_RIGHT)
 49            {
 50                 // 向右鍵按下
 51            }
 52            else if (pMsg->wParam == VK_LEFT)
 53           {
 54                 // 向左鍵按下
 55            }
 56            else if (pMsg->wParam == VK_UP)
 57            {
 58                 // 向上鍵按下
 59            }
 60            else if (pMsg->wParam == VK_SHIFT)
 61            {
 62                 //VK_LSHIFT 為左 Shift 鍵按下
 63                 //Shift 鍵按下
 64            }
 65            else if (pMsg->wParam == VK_CONTROL)
 66            {
 67                 //Ctrl 鍵按下
 68            }
 69            else if (pMsg->wParam>=VK_NUMPAD0 && pMsg->wParam<=VK_NUMPAD9)
 70            {
 71                 // 小鍵盤數字鍵按下
 72            }
 73            else if (pMsg->wParam>=0x30 && pMsg->wParam<=0x39)
 74            {
 75                 // 數字鍵按下 ( 我記得不能使用 VK_0)
 76            }
 77            else if (pMsg->wParam>=0x41 && pMsg->wParam<=0x5A)
 78            {
 79                 // 鍵盤字母鍵按下 ( 我記得不能使用 VK_A)
 80            }
 81            else if (pMsg->wParam == VK_BACK)
 82            {
 83                 // 退格鍵按下
 84            }
 85            else if (pMsg->wParam == VK_DELETE)
 86            {
 87                 // 刪除鍵按下
 88            }
 89            else if (pMsg->wParam == VK_F1)
 90            {
 91                 //F1 鍵按下
 92            }
 93 
 94            //return true;  // 使消息不再進行處理
 95      }
 96 
 97      if (pMsg->message == WM_KEYUP)
 98      {
 99            if (pMsg->wParam == VK_SHIFT)
100            {
101                 //Shift 鍵彈起
102            }
103            else if (pMsg->wParam == VK_CONTROL)
104            {
105                 //Ctrl 鍵彈起
106            }
107            //return true;  // 使消息不再進行處理
108      }
109 
110      return CDialog::PreTranslateMessage(pMsg);
111 }
112 
113 // 同時按下 ctrl 鍵
114 BOOL   CDemo_DevStudioView::PreTranslateMessage(MSG*   pMsg)   // 根據鍵盤上的按鍵對圖形進行相應的操作  
116 
117      if (pMsg->message==256)   //   256 有鍵按下, 46   DEL 鍵  
118      { 
119            switch (pMsg->wParam)   
120            { 
121                 /// 向左鍵被按下    
122            case    37
123                 { 
124                      // 同時按下了 CTRL 鍵  
125                      if (::GetKeyState(VK_CONTROL)       <       0)       
126                      {       
127                      } 
128                 } 
129            } 
130      }
131 }
posted on 2012-09-05 12:48 王海光 閱讀(1770) 評論(0)  編輯 收藏 引用 所屬分類: MFC
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲午夜久久久久久久久电影院 | 日韩视频精品在线| 国产欧美一二三区| 久久天天躁夜夜躁狠狠躁2022| 亚洲乱码国产乱码精品精| 亚洲一区精品在线| 欧美一区二区黄| 欧美一区二区三区喷汁尤物| 亚洲视频在线观看免费| 亚洲美女淫视频| 亚洲日本免费电影| 欧美成人激情在线| 亚洲砖区区免费| 亚洲第一色中文字幕| 亚洲精品老司机| 亚洲一区亚洲| 亚洲综合久久久久| 在线视频免费在线观看一区二区| 一区二区国产在线观看| **性色生活片久久毛片| 亚洲人午夜精品| 在线播放国产一区中文字幕剧情欧美 | 欧美在线影院| 久久久久久久久久码影片| 久色婷婷小香蕉久久| 久久精品动漫| 99国产精品国产精品毛片| 亚洲高清在线观看一区| 在线综合亚洲| 久久久久国色av免费看影院| 亚洲欧洲99久久| 免费91麻豆精品国产自产在线观看| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲国产你懂的| 国产精品国产三级国产普通话蜜臀 | 欧美一区不卡| 一区二区欧美在线| 亚洲欧美日韩系列| 久久青草欧美一区二区三区| 在线视频亚洲一区| 亚洲一区日韩在线| 亚洲精品系列| 亚洲中午字幕| 亚洲永久免费av| 欧美视频一区在线| 亚洲精选91| 久久综合狠狠综合久久综合88| 欧美mv日韩mv国产网站| 亚洲国产精品久久久久婷婷老年| 中文精品视频| 欧美高清视频| 亚洲激情在线| 你懂的视频一区二区| 亚洲欧美在线免费| 午夜欧美精品| 国产日韩亚洲欧美综合| 国产欧美一区二区三区久久人妖| 欧美国产一区二区在线观看| 欧美国产视频一区二区| 亚洲欧美在线免费| 正在播放欧美一区| 亚洲午夜激情| 欧美激情一区二区三区四区| 一区二区三区偷拍| 久久综合色影院| 亚洲高清视频在线| 久久激情综合网| 亚洲欧美日本视频在线观看| 欧美激情视频一区二区三区免费| 亚洲欧美日韩在线综合| 欧美激情精品久久久久久蜜臀| 狠狠狠色丁香婷婷综合激情| 久久精品视频播放| 亚洲一级黄色av| 欧美激情欧美激情在线五月| 久久狠狠亚洲综合| 欧美日韩另类国产亚洲欧美一级| 亚洲美女视频在线观看| 欧美亚洲综合在线| 国产精品一区二区三区四区| 久久久视频精品| 久久国产精品亚洲va麻豆| 精品不卡一区| 欧美成人一区二区三区在线观看 | 亚洲精选久久| 狼人社综合社区| 亚洲视频久久| 欧美精品一区二区三区久久久竹菊| 国产手机视频精品| 亚洲欧美亚洲| 亚洲一区二区三区四区五区黄| 欧美涩涩视频| 欧美一区二区三区视频| 欧美一级网站| 最新国产成人在线观看| 亚洲精品视频在线播放| 欧美日韩的一区二区| 亚洲视频电影图片偷拍一区| 亚洲女女女同性video| 国产精品久久久久久久久久久久久| 午夜精品久久久久影视 | 日韩视频免费在线观看| 欧美日韩精品在线| 欧美一区影院| 美女任你摸久久| 一区二区三区鲁丝不卡| 亚洲天堂网在线观看| …久久精品99久久香蕉国产| 99re国产精品| 在线国产亚洲欧美| 国产精品99久久久久久久vr| 尤物视频一区二区| 亚洲一区二区影院| 激情综合网址| 亚洲欧洲精品一区二区三区不卡| 欧美视频亚洲视频| 久久久久成人精品免费播放动漫| 久久国产精品网站| 亚洲作爱视频| 麻豆亚洲精品| 另类专区欧美制服同性| 国产精品成人久久久久| 欧美风情在线| 欧美一区二区在线免费观看| 久久精品二区三区| 欧美与欧洲交xxxx免费观看| 欧美午夜精品久久久久久浪潮| 免费不卡亚洲欧美| 国产一区二区av| 亚洲综合社区| 韩国成人理伦片免费播放| 亚洲欧美精品中文字幕在线| 亚洲精品影院| 91久久国产自产拍夜夜嗨| 影音先锋久久久| 久久成人精品一区二区三区| 欧美在线亚洲在线| 国产精品视频xxxx| 亚洲欧美99| 欧美专区一区二区三区| 国产精品入口66mio| 亚洲欧美国产视频| 欧美影院成年免费版| 国产欧美日韩精品一区| 午夜精品一区二区在线观看| 欧美一区二区福利在线| 国产综合视频| 亚洲欧美日韩精品久久| 亚洲精品欧美日韩专区| 欧美在线免费观看视频| 免费日韩成人| 在线成人欧美| 久久国产精品99久久久久久老狼| 亚洲欧美久久久| 欧美日韩专区在线| 先锋影音网一区二区| 久久久999精品免费| 亚洲高清自拍| 欧美视频二区| 欧美亚洲综合另类| 你懂的国产精品| 国产日韩欧美一区二区三区四区| 一区二区三区精品久久久| 亚洲欧美日韩精品久久久久| 国产麻豆综合| 久久久久91| 欧美激情日韩| 午夜精品久久久久久久白皮肤 | 亚洲肉体裸体xxxx137| 中日韩在线视频| 国产精品丝袜91| 久久久久成人精品免费播放动漫| 亚洲欧美在线播放| 一区在线影院| 欧美亚洲一区二区在线| 欧美在线日韩| 亚洲精选中文字幕| 国产精品久久久久久久9999| 亚洲女同精品视频| 亚洲欧美日韩中文在线制服| 国产中文一区二区| 久久久亚洲人| 亚洲香蕉网站| 久久精品99无色码中文字幕| 国产精品国色综合久久| 久久三级视频| 亚洲国产一区二区三区高清| 欧美三区美女| 久久久久久69| 日韩视频在线观看国产| 美国十次成人| 午夜精品福利一区二区三区av| 亚洲精品精选| 国产精品成人v| 久久精品国产69国产精品亚洲| 亚洲青涩在线| 欧美福利一区二区| 蜜臀av性久久久久蜜臀aⅴ| 亚洲国产高清一区| 国产精品久久久久高潮|