2017-07-04 75 views
2

MSDN文档说,Lparam型第15位被用于重复计数,但它说,它不是累计WM_KEYDOWN重复计数?

现在,除非我在这里失去了一些东西,它为什么称之为重复计数,但说这是不累积?

这是一个矛盾的陈述?它说它有,但它不?或者我在这里错过了什么?

我实际测试,并与位运算符掩盖它LParam&0xFFFF提取前15位,不管我有多么按住键,这个值也保持为1

,除非我做错了什么或失踪一些东西,我不知道这个计数器不重要的是什么?或者我误解了一些东西,并且做错了这个方法,并且有一些事情需要使用这个

这将是非常有效和方便的有这个计数器,所以我不必运行所有这些其他的代码为按下并保持的按键计算重复计数,那么可以使用前15位来完成吗?也许增加前15位?

+0

它没有累积,因为它不会按顺序按键,直到键被释放。我期望如果你的消息循环缓慢地处理消息,使得多个按键在循环之间进行注册,那么GetMessage(或者它是否为TranslateMessage?)将生成一个大于1的计数的单个消息。 –

回答

2

让我们开始在documentation

当前消息的重复计数。该值是由于用户按下键而导致键击自动重复的次数。

这部分是比较直接的。重复计数字段是键的“按键次数”。

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

根据您的消息循环,可以发送多条消息。只要密钥关闭,Windows就会一直发送消息,因此您可以继续处理重复。

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

重复计数不会在消息之间传递。换句话说,每条消息表示自上次处理消息后的重复次数。

您从未看到重复次数超过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_KEYDOWN保持流水账,直到WM_KEYUP。设计使您可以在事件进入时处理事件。(图片一个文本框:响应性要求您在进入时处理这些键,而不是等到该键被释放。)

+0

所以基本上,在处理该消息之后,WND_PROCEDURE函数结束,下一个消息在消息队列中处理,它恰好与WM_KEYDOWN中的自动重复中的键相同,并且它仅将前15个位显示为1,并且之前完成前15位再次递增并去处理下一个消息等,这是正确的? – sporingGT

+0

是的,你明白了。 – theB

+0

谢谢你,是的,我实际上是在WNDPROC函数中打印出WM_KEYDOWN的开关子句中的前15位的值,所以由于程序流由该函数指针控制,所以我可以看到它为什么做什么它现在确实 – sporingGT