0

これは私の最初の投稿です。私は頭痛の種になる大きな問題を抱えています。WinForms、TTS (Text-To-Speech) 音声、および状態付きのカスタム ボタンを使用するアプリがあります。

1 番目のフォーム -main- でボタンをクリックすると、アプリは 1 番目の上に 2 番目のフォームを開きます。Ok。ボタンを押して 2 番目のフォームを閉じると、TTS に何かを伝えると、フォームが閉じて、最初のフォームが再び表示されます。Ok。

問題は、2 番目のフォームのボタンを 2 回クリックしたときに発生します。TTS が何かを言い、ボタンが閉じ、「2 番目のクリック」がまだクリック バッファー (またはどこか) にあり、1 番目のフォーム (これは最初にボタンを押したときに 4 秒後に表示されます)。同期モードで音声を使用しています。非同期モードで音声を使用すると、アプリケーションはナイス例外で終了します。2 番目のフォームで 3 回または 4 回クリックすると、他のクリックはバッファに残り、常に 1 番目のフォームをクリックします。

(1)DoubleClickイベントを削除、(2)ボタンに関連付けられたイベントを削除、(3)2番目のフォームから戻ったときに自動的にクリックされるボタンを非表示、(4)作成前に1番目のフォームを非表示にしようとしました2番目に終了したら復元します。

提案?ありがとう!

PD: 私の英語でごめんなさい :S

PD2:何が起こるかの非常に簡単な例をアップロードしました。

4

2 に答える 2

0

ブール値フラグを使用して、フォームがクリックを受け入れる状態にあるかどうかを追跡します。

IE - 2 番目のフォームを開くと、'boolean canPlaySound = true;' となります。ボタン クリック イベントが発生すると、canPlaySound が true の場合にのみサウンドが再生されます (サウンドを再生する前に false に設定されます)。

canPlaySound = false のため、次のクリックは無視されます。サウンドを再生しません。

于 2011-04-26T15:50:58.957 に答える
0

編集2

コードを見て、あなたが今抱えている問題を理解しました。ボタンのクリックが積み重なっている理由は、TTS 内で Speak を呼び出すと、関数が終了するのを待っている間にアプリケーションがロックされるためです。その時間内のプレスは、アプリケーションが再び自由に処理できるようになるまで積み上げられます。その後、メッセージが処理される前にフォームを即座に閉じ、これらは最初のフォームで処理されます。

私はあなたのために働くことができるいくつかの解決策を考え出しました:

  1. TTS クラス内で SpeakAsync コマンドのみを使用し、何もする前にスピーチが終了するのを待つ待機システムを導入します。これにより、アプリケーションが解放され、マウス クリック イベントが発生しなくなります。

  2. Speak コマンドをトリガーした後、Windows メッセージ リストにアクセスし、プロセスが完了する前に発生したすべてのマウス クリック イベントをクリアできます。残念ながら、私は以前にこれを行ったことがないので、これをどのように実装するかわかりません。WndProc 関数を上書きする必要があると思いますが、やはりわかりません。これは、完全に有効な、または重要なシステム メッセージを誤って消去してしまう可能性があるため、少し危険な場合もあります。申し訳ありませんが、これ以上のヘルプは提供できません。

  3. バックグラウンド スレッドで Speak コマンドを個別に処理するバックグラウンド ワーカーを 2 番目のフォームに実装します。これにより、アプリケーションが再び解放されるため、マウス クリック イベントがスタックしなくなります。サンプル プロジェクトを変更し、zip 形式で圧縮しました。必要に応じてさらに説明できますが、基本的には次のことを行います。

    • Form 2 がバックグラウンド ワーカーを読み込んで作成します。
    • Worker_DoWork および Worker_WorkComplete デリゲートが作成され、バックグラウンド ワーカーに設定されます。これらの関数は、ワーカーの開始時と終了後に呼び出されます。
    • フォーム 2 は、バックグラウンド ワーカーの開始をトリガーします。バックグラウンド ワーカーは、コマンドが処理されるのを待つ無限ループに入ります。
    • 「Hello」ボタンが押されると、SayHello ブール値が true に設定され、ワー​​カーはこれを検出し、適切な発言機能を実行してから、次のプレスに備えてブール値をリセットします。
    • [閉じる] ボタンが押されると、CancelASync 要求がバックグラウンド ワーカーで呼び出されます。
    • CancelASync は、BackgroundWorker のメイン ループを中断します (CancellationPending が true になります)。BackgroundWorker のメイン ループから抜ける前に、適切な speak コマンドが送信され、DoWorkEventArgs の cancel プロパティが true に設定されます。
    • メイン ループから抜け出すと、フォームが閉じられる場所で Worker_WorkComplete が呼び出されます。

例 (以下にリンク) に従っていただければ幸いです。ここで十分に説明しました。たとえば、メインのワーカー スレッド内にさらに条件を追加することができます。

私が言ったように、質問があれば聞いてください。できる限りお手伝いします。

お役に立てれば。

リンクの例: http://www.mediafire.com/?2mf1yahto50ljs6

于 2011-04-26T19:27:06.333 に答える