2014-09-28 89 views
0

我試圖複製一些十六進制編輯器的行爲,它分別處理WM_KEYDOWN和WM_CHAR,它們都按照相應的順序到達。在那裏,它看起來是這樣的:WM_KEYDOWN到達,WM_CHAR被跳過

case WM_CHAR: 
    if(GetKeyState(VK_CONTROL) & 0x8000)return 0; 
    c[0] = (char)(wParam&0xFF); 
    c[1] = 0; 
    InputData(c); 
    return 0; 

case WM_KEYDOWN: 
    if(GetKeyState(VK_CONTROL) & 0x8000){ 
     switch(wParam){ 
     case 0x43: //Ctrl+C 
      MemViewCallB(hMemView,WM_COMMAND,MENU_MV_EDIT_COPY,0); 
      return 0; 
     case 0x56: //Ctrl+V 
      MemViewCallB(hMemView,WM_COMMAND,MENU_MV_EDIT_PASTE,0); 
      return 0; 
     case 0x5a: //Ctrl+Z 
      UndoLastPatch(); break; 
     case 0x41: //Ctrl+A 
      // Fall through to Ctrl+G 
     case 0x47: //Ctrl+G 
      GotoAddress(hwnd); break; 
     case 0x46: //Ctrl+F 
      OpenFindDialog(); break; 
     } 
    } 
    return 0; 

我的代碼是這樣的:

case WM_CHAR: { 
    if (GetKeyState(VK_CONTROL) & 0x8000) return 0; 
    char c[2], result = -1; 
    c[0] = (char) wParam & 0xFF; 
    c[1] = 0; 
    if (MouseArea == TEXT) { 
     //parse as a character 
    } else { 
     //parse as a number 
     } 
    } 
    return 0; 
} 

case WM_KEYDOWN: 
    if (GetKeyState(VK_CONTROL) & 0x8000) { 
     switch(wParam) { 
     case 0x43: // Ctrl+C 
      HexEditorProc(HexEditorHWnd, WM_COMMAND, IDC_C_HEX_COPY_AUTO, 0); 
      return 0; 
     case 0x47: // Ctrl+G 
      HexEditorProc(HexEditorHWnd, WM_COMMAND, IDC_C_HEX_GOTO, 0); 
      return 0; 
     } 
    } 
    return 0; 

而且只有WM_KEYDOWN到達。

當然,我試圖做這一切留在WM_KEYDOWN,通過處理所有的印刷機外(GetKeyState(VK_CONTROL) & 0x8000)作爲一個字符,將它們轉換使用ToUnicode()爲Unicode,但我得到了傳遞給它的損壞在PROC結束變量。出於某種原因,沒有關於如何使用它的深層教程ToUnicode()。所以,我想用2級不同的消息會和他們中的一個跳過另一個...

消息循環是這樣的:

while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
{ 
    if (HexEditorHWnd && IsDialogMessage(HexEditorHWnd, &msg)) 
      // stuff? 
     continue; 
    if (RamWatchHWnd && IsDialogMessage(RamWatchHWnd, &msg)) 
    { 
     if(msg.message == WM_KEYDOWN) // send keydown messages to the dialog (for accelerators, and also needed for the Alt key to work) 
      SendMessage(RamWatchHWnd, msg.message, msg.wParam, msg.lParam); 
     continue; 
    } 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

我要補充16進制軟件讓之前繼續嗎?

+0

調用ToUnicode()是TranslateMessage()的工作。如果你沒有得到WM_CHAR,它似乎從你的消息循環中丟失了。我從這裏看不到它。 – 2014-09-28 22:07:29

+0

輪詢消息而不從隊列中刪除它們不會很好地結束。你的'PeekMessage'調用應該真的刪除這個消息,因爲它正在處理它(或者試圖反正)。另請注意['WM_CHAR'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646276.aspx)的文檔:*「當WM_KEYDOWN發佈到帶有鍵盤焦點的窗口''TranslateMessage'函數翻譯消息。「*如果你想要'WM_CHAR'消息,不要跳過對'TranslateMessage'的調用(就像你正在做的那樣)。 – IInspectable 2014-09-30 06:45:52

回答

0

這個小加法似乎解決了我的問題。

if (HexEditorHWnd && IsDialogMessage(HexEditorHWnd, &msg)) 
{ 
    if(msg.message == WM_CHAR) 
     SendMessage(HexEditorHWnd, msg.message, msg.wParam, msg.lParam); 
    continue; 
} 
1

您可能不會在您的消息循環中調用TranslateMessage

while (GetMessage(&msg, 0, 0, 0) > 0) 
{ 
    TranslateMessage(&msg); // here 
    DispatchMessage(&msg); 
} 

TranslateMessage負責,除其他外,從WM_KEYDOWN產生WM_CHAR消息。

+0

我打電話給它,但它只是跳到「繼續」。將其添加到問題中。 – feos 2014-09-29 13:48:54

+0

你的消息循環不會跳到'繼續','continue'跳過'TranslateMessage'和'DispatchMessage'的調用。 – 2014-09-29 13:54:57