1.問題描述
基於MFC窗口嵌套IE內核的3D遊戲,在遊戲聊天界面,如果用戶輸入了VK_BACK按鍵,那麼此時在輸入其他字符或者按鍵都無法響應,導致用戶輸入無效(僅僅VK_BACK有效)。
2.問題分析
1.3D遊戲放在IE瀏覽器運行=》正常
2.3D遊戲通過MFC窗口運行之後,將遊戲脫離窗口設置爲獨立的窗口,運行正常
3.建立一個空的MFC工程,將遊戲嵌套進去,現象復現
所以綜上分析我們得出是MFC在傳輸VK_BACK消息導致的,並非嵌套框架導致的,那麼到底是系統按鍵出發的bug還是字符顯示出發的bug呢。
3.問題解決
通過上述分析我們初步解決方案就是PreTranslateMessage攔截VK_BACK消息。
錯誤實現:
if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_BACK)) {
return TRUE;
}
這樣雖然可以攔截VK_BACK,但是導致VK_BACK沒辦法刪除字符。
因爲我們使用鍵盤VK_BACK的功能是刪除字符,而不是顯示字符VK_BACK。所以我們可以換種實現方式
正確實現:
if ((pMsg->message == WM_CHAR) && (pMsg->wParam == VK_BACK)) {
return TRUE;
}
此時只是界面功能正常。
4.問題結論
是由於3D遊戲處理鍵盤WM_CHAR爲VK_BACK消息觸發而導致的。但是由於是第三方的遊戲,所以我們只做消息攔截處理。
5.修改後的源碼
virtual BOOL PreTranslateMessage(MSG* pMsg)
{
if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)) {
return FALSE;
}
if ((pMsg->message == WM_CHAR) && (pMsg->wParam == VK_BACK)) {
return FALSE;
}
BOOL has_process = FALSE;
if (m_spPlaceActiveObject != NULL) {
HRESULT hr = m_spPlaceActiveObject->TranslateAcceleratorW(pMsg);
if (S_OK == hr) {
has_process = TRUE;
}
}
if (has_process) {
return TRUE;
}
return CWindow::IsDialogMessage(pMsg);
}