【问题标题】:Determine whether WM_KEYDOWN's wParam is printable判断 WM_KEYDOWN 的 wParam 是否可打印
【发布时间】:2014-04-19 10:46:39
【问题描述】:

我试图在我的窗口的WM_KEYDOWN 消息中检测不可打印的字符,但迄今为止的研究没有产生任何结果。我尝试了以下方法:

  • 1:iscntrl(wParam),对方向键不起作用
  • 2:ischar(wParam),这也不适用于相同的键
  • 3:ToAscii(wParam, MapVirtualKey(wParam, 0) ...),还是不行

IMO 第三种方法应该可以工作,因为箭头键不在任何 ASCII 或 Unicode 表上。

问题是我想将键码和字符都发送给我的事件处理程序。由于WM_CHAR 是在WM_KEYDOWN 之后发布的,如果密钥不可打印,我只想发送WM_KEYDOWN 中的密钥(因为WM_CHAR 不会发送到窗口,所以我不能在那里做)。

谢谢

【问题讨论】:

  • MapVirtualKey() 的参数错误,请改用 MAPVK_VK_TO_CHAR。不使用 WM_CHAR 是不明智的,您的消息循环无法解决任何问题。
  • 有时无法使用 WM_CHAR,因为对话框的控件处理关键消息,而对话框从不接收它。

标签: c++ winapi key ascii


【解决方案1】:

鉴于大多数通常被认为是“可打印”的键都是连续的,为什么不直接使用一些 if 语句来决定如何处理它们呢?在 WM_KEYDOWN 中,判断一个键是否“可打印”,如果是,将其触发到 WM_CHAR。

您正在研究的函数并不是为这个特定目的而设计的,因此具有讽刺意味的是,您可能会花费更多的时间来研究它们,而不是自己制作一个临时解决方案。

【讨论】:

    【解决方案2】:

    您的方法#3 应该适用于此。在PreTranslateMessage,处理WM_KEYDOWN

    BYTE keyboardState[256];
    ::GetKeyboardState(keyboardState);
    WORD ascii;
    int len = ::ToAscii(wParam, (lParam >> 16) & 0xFF, keyboardState, &ascii, 0);
    if (len == 1)
    {
        /* it's printable */
        printf("%c", ascii & 0xFF); 
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多