日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows消息机制-PreTranslateMessage

發布時間:2023/12/18 windows 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows消息机制-PreTranslateMessage 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PreTranslateMessage作用和使用方法

Windows消息機制的流程:

  A. 操作系統接收應用程序的窗口消息,將消息投遞到該應用程序的消息隊列中

  B. 應用程序在消息循環中調用GetMessage函數從消息隊列中取出一條一條的消息,取出消息后,應用程序可以對消息進行一些預處理。

  C. 應用程序調用DispatchMessage,將消息回傳給操作系統。

  D. 系統利用WNDCLASS結構體的lpfnWndProc成員保存的窗口過程函數的指針調用窗口過程,對消息進行處理。

??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就有機會進行處理。

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

/*************************二*******************/

函數原型:virtual?BOOL?PreTranslateMessage(?MSG?*pMsg)?

1、在MFC中,PreTranslateMessage是虛函數,是用來截獲消息的。我們可以通過重載它來處理鍵盤和鼠標消息。在sdk中,這有所不同,我們必須在回調函
數 LRESULT???CALLBACK???WndProc(HWND???hWnd,???UINT???message,???WPARAM???wParam,???LPARAM???lParam)中處理消息。它和PreTranslateMessage起的作用是類似的,只是MFC封裝的更好而已。
2、重載該函數可以實現窗口消息在派發給窗口函數TranslateMessage()和DispatchMessae()之前的過濾,缺省的實現是完成加速鍵的翻譯。?

3、?該函數表示在消息處理(TranslateMessge()和DispatchMessage()等)前所作的操作,如果函數返回值為TRUE,那么消息?處理即終止,不會調用TranslateMessge()和DispatchMessage()來翻譯和分發消息給相應的窗口;若返回值為FALSE,才?會調用翻譯和分發消息函數。

4、在win32程序中,關于消息有兩種傳遞方式:
a.?MFC消息,MFC會把所有的消息一條條放到一個AFX_MSGMAP_ENTRY結構中,形成一個數組,該數組存放了所有的消息和與它們相關的參數。也可以說消息是放到消息隊列里去了。?b.?采用SendMessage()或其他類似的方式向窗口直接發送的而不經過消息隊列的消息。?這兩種方式中只有第一種(穿過消息隊列的消息)才受PreTranslateMessage()影響,第二種消息并不會理睬PreTranslateMessage()的存在。
?
一、是否調用TranslateMessage()和DispatchMessage()是由PreTranslateMessage()函數的返回值決定的,如果該函數返回TRUE,則不會把該消息分發給窗口函數處理。
二、傳給PreTranslateMessage()的消息是未經翻譯過的消息,它沒有經過
TranslateMessage()處理。例如:可以在該函數中使用(pMsg->wParam?==?VK_RETURN)來攔截回車鍵,其中wParam中存放的是鍵盤上字符的虛擬碼。
三、在WindowProc里不能處理WM_Char消息。(WindowProc函數見MFC消息響應機制一文)
四、SetWindowText會發送WM_Char給窗口。

、PeekMessage和GetMessage的區別:
????GetMessage在沒有消息的時候等待消息,cpu當然低
????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()函數的小程序示例:
BOOL?CSearchuserDlg::PreTranslateMessage(MSG*?pMsg)?

{
?????????? if(pMsg->message==WM_KEYDOWN)??//判斷是否有按鍵按下?????

?????????? {
????????????????? switch(pMsg->wParam)????????

?????????? {
???????????????????? case?VK_DOWN:?????//表示是方向鍵中的向下的鍵???????????????//add?handle?code?here???????????

??????? ? ? ? ????????? break;
??????????????????? case?VK_UP:??????//表示是方向鍵中的向上的鍵????????????????//add?handle?code?here???????????

??????????????????????? break;???????????

???????????????? default:???????????

????????????????????? break;????????

?????????? }????

?????? }?

}
**********************************************************************
PeekMessage?一般是用來重載消息循環,避免程序停止響應。???????????舉例:????????
??MSG???msg;???
??if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{??????????

??????? if(msg.message==WM_QUIT)??????????

????????? {???
????????????::PostQuitMessage(-1);????????????

???????? }???

????????if(!AfxGetApp()->PreTranslateMessage(&msg))????????????

?????? {???
????????????::TranslateMessage(&msg);????????????????

??????????? ::DispatchMessage(&msg);????????????

??????? }??????

}
******************************************************************************
界面上有很多個控件,如edit,如何知道當前的焦點是在哪個控件上面?
1.?GetFocus()可以得到當前控件的句柄,?你再枚舉子窗口句柄判斷,?跟得到的句柄一致的即為哪個被點中。
2.?CWnd*?pCtrl?=?CWnd::GetFocus();??

int?iCtrlID?=?pCtrl->GetDlgCtrlID();??

if(iCtrlID?==?IDC_EDIT1)??{??}?
else?if(iCtrlID?==?IDC_EDIT2)??{??}??...?
3.?GetFocus()?功能:確定當前焦點位于哪個控件上。函數執行成功時返回當前得到焦點控件的窗口句柄,發生錯誤時返回無效引用。
用法:?應用程序利用IsValid()函數可以檢測GetFocus()是否返回有效的控件引用。同時,使用TypeOf()函數可以確定控件的類型。
?

總結

以上是生活随笔為你收集整理的Windows消息机制-PreTranslateMessage的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产一区导航 | 久久久久久九九 | 国产真实乱人偷精品视频 | 欧美女优一区二区 | 国产视频一区在线 | 国产一级免费片 | 天天做日日做 | 日韩一级大片 | 国产一区91 | 免费高清欧美大片在线观看 | 色视频一区二区 | h片在线观看视频 | 一区二区三区麻豆 | 亚洲中文无码久久 | 国产精品3 | 琪琪色视频| 夫妻精品 | 最新精品国产 | 久久av免费观看 | 欧美日韩一区二区三区在线观看 | 亚洲av无码一区二区三区性色 | 制服 丝袜 综合 日韩 欧美 | 亚洲欧洲成人精品久久一码二码 | 麻豆 国产 | 四虎影视在线播放 | 黄色一级片免费在线观看 | av不卡在线播放 | 99色播| 欧美日韩中文字幕一区 | 一区二区成人免费视频 | av最新网| 天堂av在线网 | 欧美 日韩 国产 高清 | 韩国成人在线视频 | 国产日韩久久久 | 免费特级黄毛片 | 自拍日韩亚洲一区在线 | 西方裸体在线观看 | 欧美日韩免费在线 | 成人毛片av | 中文字幕在线播放视频 | 国产中文字幕91 | 亚洲天堂av网站 | 亚洲精品女人久久久 | 免费天堂av| 视频在线观看电影完整版高清免费 | 亚洲第一免费 | 人妖ts福利视频一二三区 | 天天插美女 | 日韩视频专区 | www.国产| 中文字幕二区在线观看 | 亚洲精品视频在线观看免费 | 久久六六 | 国产精品v日韩精品v在线观看 | 日本精品在线观看视频 | 欧美一区三区三区高中清蜜桃 | 久久久久久久性 | 精品日韩在线播放 | 理论片大全免费理伦片 | 偷偷在线观看免费高清av | 极品尤物一区二区三区 | 99热国产精品 | 欧美视频福利 | 综合久久影院 | 天堂成人国产精品一区 | 天天综合精品 | 成人高清视频免费观看 | 少妇与公做了夜伦理 | 爱爱福利社| 美女被爆操网站 | 91免费版视频 | 三上悠亚亚洲一区 | 天天摸天天 | 无码人妻精品一区二区中文 | www.99re7.com| v888av| 国产精品九九九九 | 国产免费无码XXXXX视频 | 婷婷视频在线观看 | 国产山村乱淫老妇女视频 | 国产妞干网| 一级二级毛片 | 理论片第一页 | 九九激情网 | 免费看操片 | 亚洲3p | 中文字幕999 | 日日夜夜精品免费视频 | 老湿福利影院 | 久久久不卡国产精品一区二区 | 亚洲欧洲一级 | 午夜久久乐 | www色com| 国产不卡在线观看 | 色四月婷婷 | 狠狠人妻久久久久久综合 | 欧美不卡在线视频 | 劲爆欧美第一页 |