2014-09-28 83 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