2010-03-14 80 views
4

如何处理按键和键入Windows消息循环中的事件?我需要能够调用两个函数OnKeyUp(char c);OnKeyDown(char c);键盘输入&Win32消息循环

我从google搜索到的当前文献引起了我对WM_CHAR或WM_KEYUP和WM_KEYDOWN的困惑,它通常针对PDA或托管代码,而我正在使用C++。

回答

6

使用char c = MapVirtualKey(param,MAPVK_VK_TO_CHAR);将虚拟键码转换为char,并处理WM_KEYUP和WM_KEYDOWN及其wParams。

if (PeekMessage (&mssg, hwnd, 0, 0, PM_REMOVE)) 
{ 
    switch (mssg.message) 
    { 
     case WM_QUIT: 
      PostQuitMessage (0); 
      notdone = false; 
      quit = true; 
      break; 

     case WM_KEYDOWN: 
      WPARAM param = mssg.wParam; 
      char c = MapVirtualKey (param, MAPVK_VK_TO_CHAR); 
      this->p->Input()->Keyboard()->Listeners()->OnKeyDown (c); 
      break; 

     case WM_KEYUP: 
      WPARAM param = mssg.wParam; 
      char c = MapVirtualKey (param, MAPVK_VK_TO_CHAR); 
      this->p->Input()->Keyboard()->Listeners()->OnKeyUp (c); 
      break; 
    } 
    // dispatch the message 
    TranslateMessage (&mssg); 
    DispatchMessage (&mssg); 
} 
11

一个典型的C++消息循环看起来像这样

MSG msg; 
while (GetMessage(&msg, null, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

的TranslateMessage的功能是产生从WM_KEYDOWN消息WM_CHAR消息,因此,如果你想看到你需要确保将消息传递WM_KEYDOWN到WM_CHAR消息它。如果你不关心WM_CHAR消息,你可以跳过它,并做这样的事情。

extern void OnKeyDown(WPARAM key); 
extern void OnKeyUp(WPARAM key); 

MSG msg; 
while (GetMessage(&msg, null, 0, 0)) 
{ 
    if (msg.message == WM_KEYDOWN) 
     OnKeyDown (msg.wParam); 
    else (msg.message == WM_KEYUP) 
     OnKeyUp(msg.wParam); 
    else 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

请注意,OnKeyDown和OnKeyUp消息被定义为采用WPARAM而不是char。这是因为WM_KEYDOWN和WM_KEYUP的值不限于适合char的值。请参见WM_KEYDOWN

+1

这里的问题是,虽然我现在有代码运行键和键,我也有代码是不可移植的。我需要一种将WPARAM转换为更具可移植性的方法,而不是将所有跨平台代码都取出来并仅将其设置为窗口,以便我可以测试虚拟键值,因此使用'char'。我也不想花费一天的时间为每个字符写入代码进行转换 – 2010-03-14 19:46:44