{
if(pMsg->message==WM_KEYDOWN)
{
bool result;
switch(pMsg->wParam)
{
case VK_RETURN:
result=this->game->Compare(this->pInput->input_number);
if (TRUE==result)
{
GameOver(TRUE);
break;
}
if(7==game->g_count)
{
GameOver(FALSE);
break;
}
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
void CGnDlg::GameOver(bool win)
{
if(TRUE==win)
{
AfxMessageBox("You Win!");
if(game!=NULL)
{
delete game;
game=NULL;
}
this->pInput->EnableWindow(0);<-就是这个语句造成反复执行case VK_RETURN:中的内容
}else
{
AfxMessageBox("You Lost!");
this->pInput->EnableWindow(0);<-就是这个语句造成反复执行case VK_RETURN:中的内容
}
}
代码如上:我把gameover中的this->pInput->EnableWindow(0);去掉后,就不会反复调用case VK_RETURN:中的内容了,也就是说this->pInput->EnableWindow(0);产生了WM_KEYDOWN消息,而且无论case VK_RETURN:和case VK_F2:中的内容都会执行,为什么会造成这种原因?
11 个解决方案
#1
PreTranslateMessage中你需要判断消息来自于什么窗口,也就是pMsg->hWnd。
#2
AfxMessageBox("You Win!");
就是不是用回车关闭的
就是不是用回车关闭的
#3
可能是这产生的
#4
在PreTranslateMessage中弹出消息框很容易让程序当掉的哟。
#5
to he_zhidan(何志丹:www.vcshare.net) :
我用鼠标和键盘的结果都是一样的
to DentistryDoctor(牙科医生) 你说的关系好像不大吧,因为它总是产生wm_keydown
我用鼠标和键盘的结果都是一样的
to DentistryDoctor(牙科医生) 你说的关系好像不大吧,因为它总是产生wm_keydown
#6
to DentistryDoctor(牙科医生) :我把对话框去掉也一样的
#7
if (TRUE==result)
{
GameOver(TRUE);
// break;
return TRUE;
}
{
GameOver(TRUE);
// break;
return TRUE;
}
#8
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主 窗口,让他们依次处理,如果其中一个处理了则结束循环。
其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后 面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主 窗口,让他们依次处理,如果其中一个处理了则结束循环。
其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后 面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
#9
up
#10
to laiyiling(最熟悉的陌生人) :
我把对话框去掉了,可问题依旧在阿
我把对话框去掉了,可问题依旧在阿
#11
to flyelf(空谷清音) :
我用你的方法就可以了,能告诉我为什么吗?我可以把分数全给你,谢谢你了!
我用你的方法就可以了,能告诉我为什么吗?我可以把分数全给你,谢谢你了!
#1
PreTranslateMessage中你需要判断消息来自于什么窗口,也就是pMsg->hWnd。
#2
AfxMessageBox("You Win!");
就是不是用回车关闭的
就是不是用回车关闭的
#3
可能是这产生的
#4
在PreTranslateMessage中弹出消息框很容易让程序当掉的哟。
#5
to he_zhidan(何志丹:www.vcshare.net) :
我用鼠标和键盘的结果都是一样的
to DentistryDoctor(牙科医生) 你说的关系好像不大吧,因为它总是产生wm_keydown
我用鼠标和键盘的结果都是一样的
to DentistryDoctor(牙科医生) 你说的关系好像不大吧,因为它总是产生wm_keydown
#6
to DentistryDoctor(牙科医生) :我把对话框去掉也一样的
#7
if (TRUE==result)
{
GameOver(TRUE);
// break;
return TRUE;
}
{
GameOver(TRUE);
// break;
return TRUE;
}
#8
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主 窗口,让他们依次处理,如果其中一个处理了则结束循环。
其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后 面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主 窗口,让他们依次处理,如果其中一个处理了则结束循环。
其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后 面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
#9
up
#10
to laiyiling(最熟悉的陌生人) :
我把对话框去掉了,可问题依旧在阿
我把对话框去掉了,可问题依旧在阿
#11
to flyelf(空谷清音) :
我用你的方法就可以了,能告诉我为什么吗?我可以把分数全给你,谢谢你了!
我用你的方法就可以了,能告诉我为什么吗?我可以把分数全给你,谢谢你了!