在这个应用程序中,我需要能够停止来自按下的键的响应,以防止不可靠的数据进入输出。我遇到的问题是,使用我下面的代码中的方法确实可以防止密钥重复,但它也会阻止它们反应不足 - 因为用户很快就会按键。
我不确定这是我的硬件,api限制还是我的代码问题,但我下面的例程并不是简单快速地完成工作而不会使程序无法使用。识别密钥是否被主动关闭(以及持续多长时间)的方法也有助于该程序的另一个功能并解决当前的问题。
有什么想法吗?
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;
}
}
答案 0 :(得分:3)
您可以使用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();
}
此示例在每次按下某个键时计算i
,并显示按下的时间。它使用GetKeyState而不是跟踪KeyDown / KeyUp,因为如果其他东西有焦点,你可能会错过这些消息。
答案 1 :(得分:0)
使用定时器:初始化定时器,每个“动作”一个(例如按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
。
答案 2 :(得分:0)
根据documentation,“每次密钥重复时都会发生[d]重复的KeyDown事件,如果按住密钥,但在用户释放密钥时只生成一个KeyUp事件。”
所以最简单的解决方案是忽略重复的KeyDown事件,除非看到相应的KeyUp事件。
为我工作。