问题:
今天李老师给了我一个类,这个类中有鼠标和键盘消息,里面要求在视类中重载PreTranslateMessage(MSG* pMsg)这个虚函数?说这个函数可以在处理消息之前截获消息,从而不影响原来的其他的操作。就上网查了下这个函数的用处回
回答:
MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流程,甚至可以作一个全新的控制流出来。只有穿过消息队列的消息才受PreTranslateMessage()影响,采用SendMessage()或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬PreTranslateMessage()的存在。
一、是否调用TranslateMessage()和DispatchMessage()是由一个名称为PreTranslateMessage()函数的返回值决定的,如果该函数返回TRUE,则不会把该消息分发给窗口函数处理。
二、传给PreTranslateMessage()的消息是未经翻译过的消息,它没有经过TranslateMessage()处理。可以在该函数中使用(pMsg->wParam==VK_RETURN)来拦截回车键。
三、在WindowProc里不能处理WM_Char消息。
四、SetWindowText会发送WM_Char给窗口。
五、PeekMessage和GetMessage的区别:
GetMessage在没有消息的时候等待消息,cpu当然低
PeekMessage没有消息的时候立刻返回,所以cpu占用率高。
因为游戏不能靠windows消息驱动,所以要用PeekMessage();
例子:
BOOL CYourWnd::PreTranslateMessage(CMsg *pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam == 'A')
{
......
}
......
}
if(pMsg->message == WM_KEYUP)
{
int nVirtKey = (int) pMsg->wParam; // virtual-key code
switch(nVirtKey)
{
case VK_UP:
//...
AfxMessageBox("Up");
break;
case VK_DOWN:
//...
AfxMessageBox("Down");
break;
case VK_ESCAPE:
AfxMessageBox("esc");
return TRUE;
break;
}