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

面對(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>
            国产精品xxxav免费视频| 一本色道久久综合亚洲精品婷婷| 亚洲午夜在线观看视频在线| 美女尤物久久精品| 午夜精品久久久久久久白皮肤| 国产美女精品视频免费观看| 欧美激情视频网站| 免费人成精品欧美精品| 久久精品视频免费| 欧美一区二区精品久久911| 欧美大片在线看免费观看| 久久精品国产视频| 久久精品99| 亚洲男人av电影| 亚洲综合电影一区二区三区| 亚洲影院在线| 亚洲日本中文字幕| 99天天综合性| 亚洲人成网站色ww在线| 亚洲国产精品va在线看黑人动漫 | 欧美一级夜夜爽| 亚洲一级在线观看| 西西裸体人体做爰大胆久久久| 久久激情视频免费观看| 欧美激情久久久| 亚洲一区二区黄| 欧美成年人视频| 国产精品一区二区三区免费观看| 国内成+人亚洲| 一区二区免费在线视频| 久久久国产亚洲精品| 亚洲大胆女人| 欧美在线视频一区| 欧美xx视频| 国产私拍一区| 一本色道久久加勒比精品| 午夜精品一区二区三区在线视| 在线观看视频亚洲| 在线不卡亚洲| 香蕉久久夜色精品国产使用方法| 女人天堂亚洲aⅴ在线观看| 99在线精品视频在线观看| 久久久久成人精品免费播放动漫| 欧美美女操人视频| 亚洲国产精品久久久久| 久久超碰97人人做人人爱| 亚洲老板91色精品久久| 六月婷婷久久| 亚洲第一免费播放区| 久久精品国产91精品亚洲| 亚洲少妇在线| 欧美性生交xxxxx久久久| 日韩午夜在线观看视频| 欧美va亚洲va国产综合| 久久久久**毛片大全| 国产综合色在线| 久久美女艺术照精彩视频福利播放| 亚洲一区二区免费在线| 欧美日韩免费高清一区色橹橹| 亚洲国产三级| 你懂的一区二区| 久久蜜桃资源一区二区老牛| 国产日韩欧美一区| 久久九九免费| 久久久免费精品| 亚洲国产一二三| 亚洲人成人一区二区在线观看| 欧美高清在线一区| 一个人看的www久久| 99国内精品久久久久久久软件| 欧美久久综合| 亚洲欧美日韩精品| 亚洲午夜成aⅴ人片| 国产精品永久入口久久久| 欧美一区二区福利在线| 欧美一区二区三区精品电影| 黄色亚洲精品| 亚洲欧洲综合| 国产精品免费小视频| 久久精品视频播放| 久久综合伊人| 亚洲午夜精品一区二区| 亚洲欧美日韩在线| 在线观看91精品国产麻豆| 亚洲国产一区在线| 国产精品电影观看| 久久综合久久88| 欧美美女福利视频| 久久成人免费视频| 欧美风情在线| 欧美一区二区女人| 亚洲曰本av电影| 亚洲精品久久久久久一区二区| 欧美视频免费在线观看| 久久国产一区| 欧美二区在线播放| 欧美一区亚洲二区| 蜜臀av一级做a爰片久久| 亚洲午夜一区| 久久婷婷一区| 亚洲欧美日韩人成在线播放| 久久久久久久波多野高潮日日| 一区二区三区波多野结衣在线观看| 亚洲香蕉网站| 亚洲每日更新| 久久久久久久97| 午夜精品久久久久久久白皮肤| 久久九九国产| 欧美一进一出视频| 欧美高清在线一区二区| 久久成人在线| 欧美视频在线不卡| 亚洲盗摄视频| 国产自产v一区二区三区c| aa成人免费视频| 亚洲国产精品v| 欧美在线视频观看| 亚洲欧美制服中文字幕| 欧美福利一区二区三区| 美日韩在线观看| 国产一区二区日韩精品| 亚洲视频欧美在线| 99视频在线精品国自产拍免费观看 | 在线一区二区三区四区| 1769国内精品视频在线播放| 亚洲欧美日韩精品久久久| 一区二区三区www| 欧美黄色网络| 亚洲二区在线| 亚洲国产美女| 另类春色校园亚洲| 欧美成人一区二区三区在线观看| 国产亚洲精品久久飘花| 亚洲欧美日韩区| 欧美在线观看视频一区二区三区| 国产精品福利在线| 99国产精品自拍| 亚洲一区二区三区视频| 欧美三级午夜理伦三级中文幕 | 国产精品欧美一区二区三区奶水| 亚洲精品久久久久久下一站 | 亚洲性感激情| 欧美日韩免费在线| 9久草视频在线视频精品| 一区二区三区四区五区精品视频| 欧美第十八页| 99精品视频网| 欧美在线观看一区二区| 国产一区二区精品丝袜| 久久精品日韩欧美| 欧美国产精品劲爆| 久久精品30| 亚洲国产乱码最新视频| 女人香蕉久久**毛片精品| 亚洲国产精品女人久久久| 亚洲精品乱码久久久久久按摩观| 欧美福利专区| 在线一区二区三区做爰视频网站| 午夜精品偷拍| 亚洲福利一区| 欧美三区在线| 欧美一区二区三区啪啪| 欧美chengren| 亚洲午夜羞羞片| 国产亚洲一区二区在线观看| 久久久久久精| 日韩一级欧洲| 久久久久国产一区二区三区四区| 亚洲国产第一| 国产精品久久久久久久免费软件 | 午夜在线精品| 欧美顶级艳妇交换群宴| 亚洲图片欧美午夜| 国产在线精品一区二区夜色| 免费成人性网站| 国产精品99久久久久久人| 免费成人av在线看| 亚洲一区二区三区激情| 影音欧美亚洲| 国产精品不卡在线| 久久综合狠狠综合久久激情| 一区二区日韩伦理片| 美日韩精品免费| 亚洲欧美日本国产专区一区| 亚洲国产一区二区三区高清| 国产麻豆日韩| 欧美人与性禽动交情品| 欧美在线一二三| 亚洲调教视频在线观看| 亚洲高清不卡一区| 噜噜噜在线观看免费视频日韩| 亚洲专区免费| 亚洲精品一区二区三区不| 国产综合久久| 国产精品午夜国产小视频| 欧美日韩1234| 欧美大片国产精品| 久久免费少妇高潮久久精品99| 亚洲永久免费| 亚洲香蕉伊综合在人在线视看|