Кнопка изменения буфера формы - PullRequest
0 голосов
/ 26 апреля 2011

это мой первый пост. У меня огромная проблема, которая вызывает у меня головную боль. У меня есть приложение, использующее WinForms, голос TTS (Text-To-Speech) и пользовательские кнопки с состояниями.

В моей 1-й форме -основной-при нажатии кнопки приложение открывает 2-ю форму над 1-й. Хорошо. Когда я закрываю 2-ую форму с помощью кнопки, я говорю TTS что-то сказать, и форма закрывается сама, снова просматривая 1-ую форму. Хорошо.

Проблема начинается, когда я нажимаю два раза на кнопке во 2-й форме: TTS что-то говорит, кнопка закрывается, и «второй щелчок» все еще находится в буфере щелчка (или где-то), и он совершает щелчок в первом форма (которая появляется через 4 секунды, когда я нажимаю кнопку в первый раз). Я использую голос в режиме синхронизации; если я использую голос в асинхронном режиме, приложение заканчивается с хорошим исключением. Если я щелкну три или четыре раза во 2-й форме, остальные клики по-прежнему останутся в буфере и все время будут нажиматься в 1-й форме.

Я пытался (1) удалить событие DoubleClick, (2) удалить событие, связанное с кнопкой, и (3) скрыть кнопку, которая автоматически нажимается при возвращении из 2-й формы, (4) скрыть 1-ю форму перед созданием 2-го и восстановлением по окончании.

Предложения? Спасибо!

PD: Извините, мой английский: S

PD2: Я загрузил очень простой пример того, что происходит.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2011

РЕДАКТИРОВАТЬ 2

Посмотрев на код, я понял проблему, с которой вы столкнулись. Причиной нажатия кнопок является то, что при вызове Speak в TTS приложение блокируется, ожидая завершения функции. Любые нажатия в это время складываются до тех пор, пока приложение снова не освободится для их обработки, затем вы мгновенно закрываете форму перед обработкой сообщений, а затем они обрабатываются в первой форме.

Я придумал несколько решений, которые могли бы вам помочь:

  1. Используйте только команду SpeakAsync в вашем классе TTS и представьте систему Ожидания, в которой вы ждете окончания речи, прежде чем что-либо делать. Это освободит приложение и не приведет к суммированию событий щелчка мыши.

  2. После запуска команды Speak вы можете получить доступ к списку сообщений Windows и очистить все события щелчка мыши, произошедшие до завершения процесса. К сожалению, я не уверен, как бы вы это реализовали, потому что раньше я этого не делал. Я думаю, что вам нужно переписать функцию WndProc, но опять же я не уверен. Это также может быть немного опасно, так как вы можете в итоге очистить совершенно правильное или важное системное сообщение по ошибке. Извините, я больше не могу вам помочь.

  3. Реализуйте фонового работника во второй форме, который будет обрабатывать команды Speak отдельно в фоновом потоке. Это снова освободит приложение, поэтому события щелчка мышью не будут складываться. Я изменил ваш пример проекта и заархивировал его, чтобы вы посмотрели. Если вы хотите, я могу объяснить дальше, но по сути это делает следующее:

    • Форма 2 загружается и создает фонового рабочего.
    • Делегаты Worker_DoWork и Worker_WorkComplete создаются и устанавливаются в фоновом режиме. Эти функции вызываются при запуске работника и после его завершения.
    • Форма 2 запускает фоновый рабочий. Затем фоновый работник сидит в бесконечном цикле, ожидая обработки команд.
    • Когда нажата кнопка «Hello», это устанавливает логическое значение SayHello на true, рабочий замечает это, выполняет соответствующую функцию разговора и затем сбрасывает логическое значение, готовое к следующему нажатию.
    • При нажатии кнопки «Закрыть» в фоновом режиме вызывается запрос CancelASync.
    • CancelASync прерывает основной цикл BackgroundWorker (CancellationPending становится истинным). Соответствующая команда выступления отправляется, и свойство отмены объекта DoWorkEventArgs устанавливается в значение true, прежде чем прерывать основной цикл BackgroundWorker.
    • Выход из основного цикла приводит к вызову Worker_WorkComplete там, где форма закрывается.

Я надеюсь, что вы можете последовать примеру (ссылка ниже), и я достаточно хорошо объяснил здесь. Я предпочитаю это решение, поскольку оно достаточно расширяемое, например, вы можете добавить больше условий в основной рабочий поток.

Как я уже сказал, если у вас есть какие-либо вопросы, пожалуйста, задавайте, и я постараюсь максимально помочь.

Надеюсь, это поможет.

Пример ссылки: http://www.mediafire.com/?2mf1yahto50ljs6

0 голосов
/ 26 апреля 2011

Используйте логический флаг, чтобы отслеживать, находится ли форма в состоянии, которое принимает щелчок.

IE - когда вы открываете 2-ю форму, 'boolean canPlaySound = true;' Когда срабатывает событие нажатия кнопки, воспроизводите звук только в том случае, если canPlaySound имеет значение true (и установите значение false перед воспроизведением звука).

Следующий щелчок будет проигнорирован, потому что canPlaySound = false. Вы не будете воспроизводить звук.

...