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

面對(duì)現(xiàn)實(shí),超越自己
逆水行舟,不進(jìn)則退
posts - 269,comments - 32,trackbacks - 0

PreTranslateMessage作用和使用方法

         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)橛螒虿荒芸?/span>windows消息驅(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)化后的代碼大概如下: 

 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在實(shí)際的TranslateMessageDispatchMessage發(fā)生之前會(huì)調(diào)用AfxPreTranslateMessageAfxPreTranslateMessage又會(huì)調(diào)用CWnd::WalkPreTranslateTree(雖然也會(huì)調(diào)用其他函數(shù),但是這個(gè)最為關(guān)鍵),其代碼如下:

 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   } 
    

可以看到,代碼還是很直接的。從接受到消息的窗口層層往上遍歷,并調(diào)用PretranslateMessage看是否返回TRUE,是則結(jié)束,否則繼續(xù)。
  這里有一個(gè)地方非常關(guān)鍵:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) 這一句代碼從當(dāng)前AfxModuleThreadState拿到Permanent句柄表,從而找到hWnd對(duì)應(yīng)的CWnd MFCPreTranslateMessageGetMessage(...)函數(shù)的下一級(jí)操作,即GetMessage(...)從消息隊(duì)列中獲取消息后,交由PreTranslateMessage()處理,若其返回FALSE則再交給TranslateMessageDispatchMessage處理(進(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)行處理。


windows
消息處理機(jī)制是這樣的:  
      
首先系統(tǒng)(也就是windows)把來(lái)自硬件(鼠標(biāo),鍵盤等消息)和來(lái)自應(yīng)用程序的消息 放到一個(gè)系統(tǒng)消息隊(duì)列中去而應(yīng)用程序需要有自己的消息隊(duì)列,也就是線程消息隊(duì)列,每一個(gè)線程有自己的消息隊(duì)列,對(duì)于多線程的應(yīng)用程序就有和線程數(shù)目相等的線程消息隊(duì)列.  
  windows
消息隊(duì)列把得到的消息發(fā)送到線程消息隊(duì)列,線程消息隊(duì)列每次取出一條消息發(fā)送到指定窗口,不斷循環(huán)直到程序退出實(shí)現(xiàn)的.這個(gè)循環(huán)就是靠消息環(huán)(while(GetMessage()) TranslateMessage();DispatchMessage();.GetMessage()只是從線程消息中取出一條消息,TranslateMessage()virtue key消息轉(zhuǎn)化成character消息,如VK_F1會(huì)轉(zhuǎn)化成WM_HELP,DispatchMessage  則把取出的消息發(fā)送到目的窗口.如果收到WM_CLOSE消息則結(jié)束循環(huán),發(fā)送postqiutmessage(0),處理WM_DESTROY毀窗口!

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

 win32 程序中,關(guān)于消息有兩種傳遞方式:

1.      MFC 消息, MFC 會(huì)把所有的消息一條條放到一個(gè) AFX_MSGMAP_ENTRY 結(jié)構(gòu)中,形成一個(gè)數(shù)組,該數(shù)組存放了所有的消息和與

它們相關(guān)的參數(shù)。也可以說(shuō)是放到消息隊(duì)列里去。

2.      采用 SendMessage() 或其他類似的方式向窗口直接發(fā)送的而不經(jīng)過(guò)消息隊(duì)列的消息。


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

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

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

 TRUE ,則不會(huì)把該消息分發(fā)給窗口函數(shù)處理。

2)      傳給 PreTranslateMessage() 的消息是未經(jīng)翻譯過(guò)的消息,它沒(méi)有經(jīng)過(guò) TranslateMessage() 處理。可以在該函數(shù)中使用 

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

3)      在 WindowProc 里不能處理 WM_Char 消息。( WindowProc 函數(shù)見(jiàn) MFC 消息響應(yīng)機(jī)制一文)

4)      SetWindowText 會(huì)發(fā)送 WM_Char 給窗口。

5)      PeekMessage 和 GetMessage 的區(qū)別:

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

7)      PeekMessage 沒(méi)有消息的時(shí)候立刻返回,所以 cpu 占用率高。因?yàn)橛螒虿荒芸?nbsp;windows 消息驅(qū)動(dòng),所以要用 PeekMessage();


另一篇文章中:

            在一個(gè) WIN32 程序中, WINDOWS 會(huì)將消息傳遞給相應(yīng)的窗口。但是消息不是立即就被傳遞給相應(yīng)的窗口,而是會(huì)從整個(gè)程序最頂層

的窗口傳遞到下一級(jí)窗 口,再傳遞到下一級(jí)窗口,直到傳遞給目標(biāo)窗口。在整個(gè)過(guò)程中,有些消息,在某些特定的情況下,無(wú)法默認(rèn)傳遞到目

標(biāo)窗口的。比如用戶在 EDIT 控件中按下回 車鍵, CANCEL 鍵等,如果 EDIT 窗口之前有對(duì)話框窗口,對(duì)話框會(huì)默認(rèn)處理回車消息(即響應(yīng) 

ONOK 函數(shù),然后關(guān)閉對(duì)話框),然后退出消息傳遞。所以 EDIT 會(huì)收不到。要解決這個(gè)問(wèn)題,可以在 EDIT 窗口之前所有的對(duì)話框中重載 

PreTranslateMessage 函數(shù),然后在函數(shù)內(nèi)加上:

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

息傳遞,如此一來(lái)雖然也能避開(kāi)對(duì)話框默認(rèn)處理,但是會(huì)退出消息傳遞,這樣 EDIT 控件照樣得不到消息。

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

他窗口中不必重載 PreTranslateMessage 函數(shù),當(dāng)然如果重載了也不會(huì)錯(cuò)。


附:關(guān)于 PreTranslateMessage() 函數(shù)的小程序示例:

  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      // 按鍵相應(yīng)
 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                 // 小鍵盤數(shù)字鍵按下
 72            }
 73            else if (pMsg->wParam>=0x30 && pMsg->wParam<=0x39)
 74            {
 75                 // 數(shù)字鍵按下 ( 我記得不能使用 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;  // 使消息不再進(jìn)行處理
 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;  // 使消息不再進(jìn)行處理
108      }
109 
110      return CDialog::PreTranslateMessage(pMsg);
111 }
112 
113 // 同時(shí)按下 ctrl 鍵
114 BOOL   CDemo_DevStudioView::PreTranslateMessage(MSG*   pMsg)   // 根據(jù)鍵盤上的按鍵對(duì)圖形進(jìn)行相應(yīng)的操作  
116 
117      if (pMsg->message==256)   //   256 有鍵按下, 46   DEL 鍵  
118      { 
119            switch (pMsg->wParam)   
120            { 
121                 /// 向左鍵被按下    
122            case    37
123                 { 
124                      // 同時(shí)按下了 CTRL 鍵  
125                      if (::GetKeyState(VK_CONTROL)       <       0)       
126                      {       
127                      } 
128                 } 
129            } 
130      }
131 }
posted on 2012-09-05 12:48 王海光 閱讀(1770) 評(píng)論(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>
            亚洲欧美在线磁力| 欧美成人午夜剧场免费观看| 欧美激情成人在线| 久久激情婷婷| 欧美日韩一区二区三区免费看| 久久精品99无色码中文字幕| 中文亚洲字幕| 91久久在线视频| 久久久久综合一区二区三区| 国产一区二区高清| 久久精品视频在线| 久久国产婷婷国产香蕉| 亚洲深夜福利视频| 99在线精品观看| 香蕉视频成人在线观看| 亚洲精品九九| 尤物精品在线| 国产精品日韩欧美大师| 久久久久久久成人| 欧美日韩调教| 欧美h视频在线| 欧美在线免费| 亚洲免费中文字幕| 中文日韩欧美| 一区二区三区www| 黄色亚洲精品| 亚洲综合导航| 欧美一区二区三区视频在线观看 | 99re成人精品视频| 原创国产精品91| 伊人久久av导航| 日韩午夜在线| 亚洲免费在线看| 久久精品欧美| 久久一区激情| 欧美午夜精品久久久久久久| 久久精品国产久精国产一老狼| 一道本一区二区| 亚洲美女色禁图| 国产精品一区二区久久久| 欧美日韩国产精品成人| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美人成在线视频| 99精品久久免费看蜜臀剧情介绍| 亚洲黄色成人网| 欧美成人资源| 亚洲啪啪91| 久久精品99国产精品日本| 久久本道综合色狠狠五月| 欧美激情一区二区三区在线视频 | 在线观看av一区| 国产一区二区三区观看| 亚洲精品久久久久久久久久久久| 亚洲尤物在线视频观看| 久久久久久夜| 欧美一区二区三区四区在线观看| 欧美亚洲免费高清在线观看| 欧美一区二粉嫩精品国产一线天| 欧美成人按摩| 午夜视频一区| 免费试看一区| 国产欧美一区二区精品忘忧草| 91久久国产综合久久91精品网站| 欧美丰满高潮xxxx喷水动漫| 亚洲激情一区| 久久久噜噜噜久噜久久| 欧美国产欧美亚洲国产日韩mv天天看完整 | 久久精品国产亚洲一区二区三区| 久久激情视频| 久久久免费精品| 亚洲高清视频的网址| 老司机午夜精品视频在线观看| 国产一区二区三区av电影| 一区在线免费观看| 欧美亚洲日本国产| 一区二区三区视频在线| 欧美成人蜜桃| 欧美日韩直播| 久久乐国产精品| 另类欧美日韩国产在线| 亚洲精品婷婷| 欧美777四色影视在线| 欧美日韩另类视频| 国产专区综合网| 欧美一区二区三区免费观看| 亚洲精品欧美日韩专区| 久久一区亚洲| 激情欧美一区二区三区| 久久精品av麻豆的观看方式| 禁久久精品乱码| 久久久一本精品99久久精品66| 亚洲一区二区三区成人在线视频精品| 欧美日韩在线播放一区二区| 亚洲素人在线| 亚洲午夜av在线| 国产一区二区你懂的| 久久婷婷人人澡人人喊人人爽| 久久精品72免费观看| 国产日韩欧美中文| 99国产精品久久久久久久久久| 亚洲国产高潮在线观看| 欧美成人一区二区三区片免费| 亚洲精品久久久久久下一站| 亚洲国产专区| 国产精品初高中精品久久| 午夜精品久久久久久久白皮肤 | 亚洲一区尤物| 欧美一二三区在线观看| 久热爱精品视频线路一| 亚洲主播在线| 噜噜噜91成人网| 欧美一区二区国产| 欧美激情麻豆| 久久伊人精品天天| 国产精品成人一区二区| 免费成人黄色片| 国产精品自在欧美一区| 亚洲三级电影全部在线观看高清| 狠狠色综合网站久久久久久久| 亚洲免费av网站| 亚洲国产专区校园欧美| 午夜精品福利一区二区三区av| aⅴ色国产欧美| 久久超碰97人人做人人爱| 亚洲大片av| 亚洲天堂偷拍| 欧美一区二区三区在线播放| 欧美日韩国产另类不卡| 9久re热视频在线精品| av成人激情| 国产欧亚日韩视频| 欧美激情一区二区三区四区| 亚洲欧美bt| 亚洲欧美日韩综合| 亚洲第一精品在线| 亚洲欧美日韩在线| 日韩系列在线| 欧美一区二区在线免费播放| 一区二区欧美在线观看| 久久夜精品va视频免费观看| 久久久www成人免费精品| 国产精品一区二区久久久久| 亚洲色图在线视频| 日韩视频专区| 欧美96在线丨欧| 亚洲国产婷婷| 99视频一区二区三区| 欧美日韩伦理在线| 亚洲欧洲久久| 在线一区二区视频| 国产精品成人在线观看| 正在播放日韩| 新狼窝色av性久久久久久| 国产精品久久久久久久久免费 | 久久婷婷久久| 蜜桃av一区二区三区| 狠狠色丁香婷婷综合久久片| 久久精品国产成人| 欧美一区二区三区免费观看| 国产免费成人在线视频| 久久狠狠久久综合桃花| 裸体一区二区| 亚洲精品国产精品国自产在线| 欧美黄色小视频| 宅男噜噜噜66一区二区66| 欧美亚洲一区三区| 国产欧美日韩不卡| 久久精品亚洲一区二区| 亚洲福利视频一区| 亚洲素人在线| 狠狠干综合网| 欧美日韩国产不卡在线看| 亚洲一区二区三区免费观看| 免费观看30秒视频久久| 一区二区欧美日韩| 国产精品日韩欧美一区| 久久久人成影片一区二区三区 | 中文在线不卡| 国产亚洲欧美日韩日本| 亚洲一区免费在线观看| 亚洲激情网站免费观看| av不卡在线观看| 国产精品亚洲一区| 久久亚洲视频| 亚洲天堂免费观看| 欧美国产极速在线| 久久成人羞羞网站| 亚洲人午夜精品| 国产手机视频一区二区| 欧美激情按摩在线| 久久成人国产精品| 亚洲精品视频中文字幕| 免费欧美高清视频| 久久精品一本| 亚洲欧美三级伦理| 亚洲免费大片| 在线看不卡av| 国产情侣一区| 欧美视频手机在线| 欧美.www|