WM_KEYDOWN重复计数?

时间:2017-07-04 06:01:00

标签: winapi

MSDN文档说LParam前15位用于重复计数,但它表示它不是累积的

现在除非我在这里遗漏了什么,为什么它称之为重​​复计数但是说它不是累积的?

这是矛盾声明吗?它说它确实但不是吗?或者我在这里错过了什么?

我实际上对它进行了测试,并使用按位运算符对其进行屏蔽,以便使用LParam&0xFFFF提取前15位,无论我按住该键多少,此值仍为1

除非我做错了什么或遗漏了什么,否则我不知道这个计数器的重点是什么?或者我误解了一些事情并以错误的方式做这件事,并且有一些事情需要做才能使用这个

使用此计数器会更加有效和方便,因此我不必运行所有其他代码来计算按下和保持的键的重复计数,因此可以使用前15位完成?也许增加前15位?

1 个答案:

答案 0 :(得分:3)

让我们从documentation开始:

  

当前消息的重复计数。该值是用户按住键时键击自动重复的次数。

这部分相对简单。重复计数字段是密钥“按下”的次数。

  

如果按键持续时间足够长,则会发送多条消息。

可以发送多条消息,具体取决于您的消息循环。只要密钥关闭,Windows就会不断向您发送消息,因此您可以继续处理重复信息。

  

但是,重复计数不是累积计数。

重复计数不会在消息之间延续。换句话说,每条消息代表自您上次处理WM_KEYDOWN消息以来的重复次数。

您从未看到重复次数超过1的原因是您正在快速处理窗口消息。通过在WM_KEYDOWN消息处理程序中添加延迟以允许更多重复进入下一条消息,您可以看到更高的数字。 (在C#中,因为样板代码较少,但您应该能够将其翻译成您使用的任何语言。)

private const int WM_KEYDOWN = 0x0100;
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_KEYDOWN)
    {
        System.Threading.Thread.Sleep(1000);
        this.Text = $"Keydown Count: {m.LParam.ToInt32() & 0xFF}";
    }
    base.WndProc(ref m);
}

运行此代码,我看到重复计数接近20-30。

如果您需要次重复次数,则需要保持从第一个WM_KEYDOWNWM_KEYUP的运行记录。设计是这样的,您可以在事件进入时对其进行处理。(图片文本框:响应性要求您在密钥进入时处理密钥,而不是等到密钥被释放。)