【问题标题】:WM_KEYDOWN, getting values from the lparam?WM_KEYDOWN,从 lparam 获取值?
【发布时间】:2011-05-06 20:05:17
【问题描述】:

在 MSDN 上,对于 WM_KEYDOWN 定义,它说 lparam 的位包含:

Bits    Meaning
0-15    The repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
16-23   The scan code. The value depends on the OEM.
24  Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28   Reserved; do not use.
29  The context code. The value is always 0 for a WM_KEYDOWN message.
30  The previous key state. The value is 1 if the key is down before the message is sent, or it is zero if the key is up.
31  The transition state. The value is always 0 for a WM_KEYDOWN message.

(http://msdn.microsoft.com/en-us/library/ms646280%28VS.85%29.aspx)

所以我创建了一个内部结构如下的联合:

union KeyState
{
    LPARAM lparam;

    struct
    {
        unsigned nRepeatCount : 15;
        unsigned nScanCode : 8;
        unsigned nExtended : 1;
        unsigned nReserved : 4;
        unsigned nContext : 1;
        unsigned nPrev : 1;
        unsigned nTrans : 1;
    };
};

然后当我在我的编辑框上收到一条 wm_keydown 消息时,我会这样打印它:

if (msg == WM_KEYDOWN)
{
    std::tstringstream ss;

    KeyState ks;
    ks.lparam = lparam;

    ss << "Key: " << (TCHAR)wparam << ", Val: " << (UINT)wparam << ", nRepeatCount: " << ks.nRepeatCount << 
        ", nScanCode: " << ks.nScanCode << ", nExtended: " << ks.nExtended << ", nReserved: " << ks.nReserved << 
        ", nContext: " << ks.nContext << ", nPrev: " << ks.nPrev << ", nTrans: " << ks.nTrans;

    SetWindowText(hOut, ss.str().c_str());
}

我在编辑框中输入时返回的值似乎不正确,有时 nReserved 甚至为 1 或 0,并且 nRepeatCount 始终为 1,无论我是否按住键登录时间或者只是按随机键。

我做错了吗?如果是这样,从 LPARAM 获取这些值的理想方法是什么?

【问题讨论】:

  • 而且 nExtended 总是 0 即使我按下 CTRL/SHIFT .. 当描述说它应该是 1 时(编辑:刚刚意识到是右手 ctrl 和 shift,似乎现在上班
  • 如果 RepeatCount 似乎总是 1,为什么它需要很短?

标签: c++ c winapi


【解决方案1】:

嗯,一方面 0-15 是 16 位,而不是 15。

【讨论】:

  • 确实如此,但仍然得到相同的结果。如果我按住 L 键(LLLLLLLLLLLLLLLLLLLLLLLLLLLL),nRepeatCount 仍然是 1.. 重复计数到底是多少?我认为它会随着您按住键的时间而增加
  • 仅当您为多个键获得一个WM_KEYDOWN 时才使用重复计数。如果您看到nRepeatCount==1,则表示您每有一个'L' 就有一个WM_KEYDOWN。当 Windows 发送 WM_KEYDOWN 消息的速度比键盘重复的速度更快时,这是非常合理的。
【解决方案2】:

是的,很容易出错(参见 500 的回答)。我会简单地使用位图和位移。

例如。 NRepeat = lparam & 0xFFFF;

【讨论】:

  • 那个,或者LOWORD(lparam)
  • Yes LOWORD 用于该示例。其他位需要掩码。我在 iPad 上打字,所以我输入了最简单的例子!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多