好的我觉得我遇到了问题。我忘记了我在全球范围内挂钩了keyUpEvent。 由于首先处理全局关键事件,因此可能发生这种现象。
我有点问题。 keyup事件发生在keydown事件之前。
我的计划应该做的是: 当用户按下某个键时,正在记录麦克风输入。 当用户释放时,键记录被停止并且正在保存wav文件。
如果用户正在按一个键,一切都很好。 但是在短时间内按下几个键会导致上述行为。 我添加了一些代码,以便我可以看到会发生什么。这是这种情况的输出。
Key down NumPad4, NumPad4, 100
128 = KeyDownTime
Key up NumPad4, NumPad4, 100
117 = KeyUpTime
Key up NumPad5, NumPad5, 101
0 = KeyUpTime
Key up NumPad6, NumPad6, 102
0 = KeyUpTime
Key down NumPad5, NumPad5, 101
58 = KeyDownTime
Key down NumPad6, NumPad6, 102
0 = KeyDownTime
你可以看到numpad5和numpad6的keyup事件发生在他们的keydown事件之前。 是否会发生2次事件但第二次事件更早结束? 我想用thread.sleep将leyup事件延迟50毫秒。 但我希望有更好的解决方案。
我没有添加任何代码,因为它是微不足道的,我不知道什么可以帮助你帮助我。 但如果你需要看它,只要告诉我将发布哪一部分。
这里编辑是代码的一部分:这里是KeyDownEvent
private void UserControl_KeyDown(object sender, KeyEventArgs e)
{
richTextBox1.AppendText("Key down"+e.KeyCode.ToString() + ", " + e.KeyData.ToString() + ", " + e.KeyValue.ToString()+"\n");
StWt1 = new Stopwatch();
StWt1.Start();
try
{
if (ready && !keyPressed)
{
switch (e.KeyData)
{
case Keys.D0:
keyPressed = true;
calib = 10.0;
calib2 = mySaver.ID;
adjustLabelDisplay(10);
break;
// this is all the same with different value for calib depending on the pressed key
case Keys.Decimal:
keyPressed = true;
calib = 100.0;
calib2 = mySaver.ID;
adjustLabelDisplay(100);
break;
default:
break;
}
}
else if (!ready)
{
MessageBox.Show("Missing at least one calibration value!");
labelDisplay.ForeColor = Color.Red;
labelDisplay.Text = "--------";
}
}
catch (Exception ex)
{
richTextBox1.Visible = true;
buttonHideRTB.Visible = true;
richTextBox1.AppendText("Exception:\n");
if (e == null)
richTextBox1.AppendText("Eventargs are Zero");
if (sender == null)
richTextBox1.AppendText("Sender is null");
if (calib == null)
richTextBox1.AppendText("calib is null");
if (calib2 == null)
richTextBox1.AppendText("calib2 is null");
richTextBox1.AppendText("Exception Message: " + ex.Message + "\n");
richTextBox1.AppendText("Exception source: " + ex.Source + "\n");
richTextBox1.AppendText("Exception Stack Trace: " + ex.StackTrace + "\n");
richTextBox1.AppendText("Exception Traget Site: " + ex.TargetSite + "\n");
MessageBox.Show("Exception was thrown. Check The Rich Text Box for further information.");
}
richTextBox1.AppendText(StWt1.ElapsedMilliseconds.ToString() + " = KeyDownTime\n");
StWt1.Stop();
}
切换部分中KeyDownevent调用的方法:
private void adjustLabelDisplay(int x)
{
calib_ValueChangedEvent();
calib2_ValueChangedEvent();
currentKey = x;
labelDisplay.Text = "Key: " + x;
labelDisplay.BackColor = Color.FromArgb(255,128,0);
this.labelDisplay.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
if (labelCB1.Text[0] != x.ToString()[0])
{
MessageBox.Show("Change to working page!");
}
if (checkBoxMode.Checked)
enhRec.startRec();
else
{
recorder.startRecordVoice();
startTime = DateTime.Now;
}
}
和keyUpEvent:
private void UserControl_KeyUp(object sender, KeyEventArgs e)
{
richTextBox1.AppendText("Key up" + e.KeyCode.ToString() + ", " + e.KeyData.ToString() + ", " + e.KeyValue.ToString()+"\n");
StWt2 = new Stopwatch();
StWt2.Start();
if (ready)
{
if (keyPressed)
{
calib2=0;
calib=0;
labelCB1.Text = "0";
labelCB2.Text = "0";
keyPressed = false;
labelDisplay.Text = "Key: ";
labelDisplay.BackColor = Color.FromArgb(100, 255, 255, 255);
this.labelDisplay.BorderStyle = System.Windows.Forms.BorderStyle.None;
if (checkBoxMode.Checked)
enhRec.saveRec(getSaveString());
else
recorder.stopRecordVoice(getSaveString(), startTime, (int)numericUpDown1.Value);
}
}
else
{
labelDisplay.ForeColor = Color.Black;
labelDisplay.Text = "Key: ";
}
richTextBox1.AppendText(StWt2.ElapsedMilliseconds.ToString() + " = KeyUpTime\n");
StWt2.Stop();
}
答案 0 :(得分:0)
您正在使用全局状态(keyPressed
成员)来存储键盘状态信息。在您的代码中任何 KeyUp
事件都会停止您的录制会话。这意味着您可以按一个键(开始录音),然后按另一个键并释放它,同时仍按住第一个键,您的录音将停止。
答案 1 :(得分:0)
如果我没有弄错的话,这些事件会在两个不同的地方处理,这就解释了为什么按键越快,结果变得越零。您看,处理KeyUp
事件的控件没有KeyDown
事件的处理程序,因此当消息泵开始进入时,您将在{{1}之前获取KeyUp
事件因为某些KeyDown
事件正在等待其他事件完成。
这是竞争条件。
在一个班级处理事件,你会没事的。