1

编辑

好的,我想我有问题。我忘记了我在全球范围内挂钩 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();
        } 

Switch部分中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;
            }
        }

和关键事件:

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();
        }
4

2 回答 2

0

如果我没记错的话,这些事件是在两个不同的地方处理的,这就解释了为什么按键越快,结果就越零星。您会看到,处理KeyUp事件的控件没有事件处理程序,KeyDown因此当消息泵开始进入时,您将在KeyUp事件之前获取KeyDown事件,因为某些KeyDown事件正在等待其他事件完成。

这是一个竞赛条件。

在一个班级中处理事件,你会没事的。

于 2012-09-27T13:44:46.227 回答
0

您正在使用全局状态(keyPressed成员)来存储键盘状态信息。在您的代码中,任何 KeyUp事件都会停止您的录制会话。这意味着您可以按下一个键(开始录制),然后按下另一个键并释放它,同时仍然按住第一个键,您的录制将停止。

于 2012-09-27T13:43:27.303 回答