Edit輸入VK_BACK,導致無法再次輸入

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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章