1

編集

問題が発生したと思います。keyUpEventをグローバルにフックするのを忘れました。グローバルキーイベントが最初に処理されるため、この現象が発生する可能性があります。

オリジナル

少し問題がありました。キーアップイベントは、キーダウンイベントの前に発生します。

私のプログラムが行うことは、ユーザーがキーを押している間、マイク入力が録音されていることです。ユーザーが離すと、キーの録音が停止し、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のキーアップイベントは、キーダウンイベントよりも早く発生しました。2つのイベントが発生しても、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();
        }
4

2 に答える 2

0

keyPressedキーボードの状態情報を格納するためにグローバル状態(メンバー)を使用しています。コード内の KeyUpイベントは、記録セッションを停止します。つまり、最初のキーを押したまま、1つのキーを押して(録音を開始)、別のキーを押して放すと、録音が​​停止します。

于 2012-09-27T13:43:27.303 に答える
0

私が間違っていなければ、これらのイベントは 2 つの異なる場所で処理されます。これが、キーを速く押すほど結果が散発的になる理由を説明しています。イベントを処理するコントロールにはKeyUpイベントのハンドラーがないKeyDownため、メッセージ ポンプが受信し始めると、KeyUpイベントの前にイベントを取得することになります。KeyDownこれは、一部のKeyDownイベントが他のイベントの終了を待機しているためです。

競合状態です。

単一のクラスでイベントを処理すれば問題ありません。

于 2012-09-27T13:44:46.227 に答える