停止重复关键点(C#)
在这个应用程序中,我需要能够停止按键的响应,这是为了防止不必要的数据进入输出。我遇到的问题是,使用我下面代码中的方法确实可以防止按键重复,但也会阻止它们响应足够快,因为用户敲击按键的速度非常快 我不确定这是我的硬件、api限制还是我的代码有问题,但我下面的例程并没有足够快的速度来工作,而不会使程序无法使用。一种确定钥匙是否被有效按下(以及按下的时间)的方法也将有助于该程序的另一个功能并解决当前问题 有什么想法吗停止重复关键点(C#),c#,winforms,keypress,keydown,C#,Winforms,Keypress,Keydown,在这个应用程序中,我需要能够停止按键的响应,这是为了防止不必要的数据进入输出。我遇到的问题是,使用我下面代码中的方法确实可以防止按键重复,但也会阻止它们响应足够快,因为用户敲击按键的速度非常快 我不确定这是我的硬件、api限制还是我的代码有问题,但我下面的例程并没有足够快的速度来工作,而不会使程序无法使用。一种确定钥匙是否被有效按下(以及按下的时间)的方法也将有助于该程序的另一个功能并解决当前问题 有什么想法吗 private void Form1_KeyDown(object sender,
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = isKeyDown;
isKeyDown = true;
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
isKeyDown = false;
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!isStreamPlaying) return;
if (e.KeyChar.Equals('d') || e.KeyChar.Equals('j'))
{
//red hit
SoundPlayer hitSounds = new SoundPlayer(taikoLiveMapper.Properties.Resources.normal_hitnormal);
hitSounds.Play();
outputlist.Add(string.Format("320,240,{0},1,{1}", ms, 0));
lastms = ms;
}
else if (e.KeyChar.Equals('s') || e.KeyChar.Equals('k'))
{
//blue hit
SoundPlayer hitSounds = new SoundPlayer(taikoLiveMapper.Properties.Resources.normal_hitclap);
hitSounds.Play();
outputlist.Add(string.Format("320,240,{0},1,{1}", ms, 8));
lastms = ms;
}
}
您可以使用GetKeyState来确定某个关键点是否已关闭,并使用它来跟踪关键点:
[DllImport("user32.dll")]
static extern short GetKeyState(int key);
static bool IsKeyPressed(Keys key)
{
short state = GetKeyState((int)key);
return ((state & 128) != 0);
}
int i = 0;
Dictionary<Keys, DateTime> downSince = new Dictionary<Keys, DateTime>();
private void UpdateKeyStates()
{
foreach (var entry in downSince.ToArray())
{
if (!IsKeyPressed(entry.Key))
downSince.Remove(entry.Key);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
UpdateKeyStates();
if (!downSince.ContainsKey(e.KeyCode))
{
downSince.Add(e.KeyCode, DateTime.UtcNow);
i++;
}
Text = i.ToString() + " " +(int)(DateTime.UtcNow - downSince[e.KeyCode]).TotalMilliseconds;
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
UpdateKeyStates();
}
[DllImport(“user32.dll”)]
静态外部短GetKeyState(int键);
按下静态布尔键(按键)
{
短状态=GetKeyState((int)键);
返回((状态&128)!=0);
}
int i=0;
字典缩减=新字典();
私有void updateKeyState()
{
foreach(递减中的var条目ToArray())
{
如果(!IsKeyPressed(entry.Key))
缩小。移除(输入。键);
}
}
私有void Form1\u KeyDown(对象发送方,KeyEventArgs e)
{
UpdateKeyState();
如果(!减小容器尺寸(e.KeyCode))
{
向下插入(例如KeyCode、DateTime.UtcNow);
i++;
}
Text=i.ToString()+“”+(int)(DateTime.UtcNow-downSince[e.KeyCode])。总毫秒数;
}
私有void Form1\u KeyUp(对象发送方,KeyEventArgs e)
{
UpdateKeyState();
}
此示例在每次按下键时统计
i
,并显示按下键的时间。它使用GetKeyState而不是跟踪KeyDown/KeyUp,因为如果其他内容有焦点,您可能会错过这些消息。使用计时器:初始化计时器,每个“操作”一个计时器(例如按d/j或s/k)在计时器内移动红色命中/蓝色命中代码,而不是当前代码,具有以下内容:
if (e.KeyChar.Equals('d') || e.KeyChar.Equals('j'))
{
//red hit
if (!tmrRedHit.Enabled)
tmrRedHit.Enabled = true;
}
else if (e.KeyChar.Equals('s') || e.KeyChar.Equals('k'))
{
//blue hit
if (!tmrBlueHit.Enabled)
tmrBlueHit.Enabled = true;
}
在定时器Elpased事件中,在代码执行后,也将其Enabled设置为false
。根据“如果按键被按下,则每次按键重复时都会发生[d]上键事件,但当用户释放按键时,只会生成一个上键事件。”
因此,最简单的解决方案是忽略重复的KeyDown事件,除非看到其相应的KeyUp事件
刚刚对我起作用。如果代码是在KeyDown或KeyPress中,问题仍然存在。这似乎现在就解决了。我不会一字不差地使用这段代码,但我将应用DirectInput的一般思想。谢谢API太慢,无法完成我希望它完成的任务。我必须用DirectInput处理所有这些代码,才能使它达到我想要的效果。那么为什么要投否决票呢?这个解决方案对您不起作用吗?您的答案确实解决了这个问题,但没有任何代码演示该解决方案。这可能就是投票失败的原因。