Как прервать диалог поиска в Delphi?

У меня есть стандартный диалог поиска:

введите здесь описание изображения

Моя программа может обрабатывать некоторые очень большие файлы, и поиск текста в таких файлах может занять 10-20 секунд и более. Поэтому после нажатия кнопки «Найти далее» я меняю курсор на песочные часы. Я меняю его обратно на стандартный указатель после того, как текст либо найден, либо не найден.

Моя проблема в том, что пользователь может решить отменить поиск и решить сделать это, нажав кнопку «Отмена». Затем кнопка «Отмена» закрывает диалоговое окно, но поиск продолжается в моей подпрограмме FindDialogFind до тех пор, пока текст не будет найден или не найден.

Я поставил точку останова при выходе из FindDialog.exe, но она не достигается, пока не завершится FindDialogFind.

Есть ли способ зафиксировать факт нажатия кнопки «Отмена», что позволит мне разорвать цикл FindDialogFind, или, может быть, есть лучший способ остановить поиск при нажатии кнопки «Отмена»?


person lkessler    schedule 09.01.2012    source источник
comment
В событии OnClose события FindDialog установите логическую переменную FStopSearch. Часто проверяйте эту переменную в своей процедуре поиска и прерывайте поиск, если она установлена.   -  person LU RD    schedule 09.01.2012
comment
@LURD - Это именно то, что я хотел бы сделать. Как настроить обработчик события OnClose для общего диалога Windows? Это не форма Delphi. И почему бы вам не дать мне это как ответ, а не комментарий?   -  person lkessler    schedule 09.01.2012
comment
Упс. Выпавший FindDialog имеет три события. FindDialogClose должен работать нормально. Спасибо. У всех нас бывают такие дни, когда ничего не замечается. Прости.   -  person lkessler    schedule 09.01.2012
comment
Хорошо, я ответил на него и добавил комментарий о компоненте TFindDialog.   -  person LU RD    schedule 09.01.2012


Ответы (2)


В событии OnClose компонента TFindDialog установите логическую переменную FAbortSearch. Часто проверяйте эту переменную в своей процедуре поиска и прерывайте ее, если она установлена.

person LU RD    schedule 09.01.2012
comment
Это, конечно, будет работать только в том случае, если процедура поиска периодически вызывает Application.ProcessMessages(), поэтому кнопка «Отмена» вообще будет работать. - person Remy Lebeau; 10.01.2012

Переместите логику поиска в рабочий поток, запускаемый при каждом нажатии кнопки Next. Когда диалоговое окно закрыто, вы можете завершить поток, если он все еще выполняется.

person Remy Lebeau    schedule 09.01.2012
comment
Я мог бы, но в этом нет необходимости, так как это становится основной задачей, которую ждет пользователь. - person lkessler; 10.01.2012
comment
Возможно, но это позволяет вам аккуратно отменить операцию поиска, не замедляя сам поиск и не вызывая побочных эффектов, путем вызова Application.ProcessMessages() во время поиска, чтобы диалог оставался чувствительным к пользовательскому вводу. Каждый раз, когда вам нужно заблокировать основной поток на какое-либо заметное время, вам следует рассмотреть возможность использования рабочего потока. Основной поток должен своевременно реагировать на очередь сообщений. - person Remy Lebeau; 10.01.2012
comment
... если бы только Delphi упростила многопоточность. Пожалуйста, передайте это Реми. - person lkessler; 10.01.2012
comment
Оно делает. Получите класс от TThread. Добавьте параметры в его конструктор, чтобы передать критерии поиска, и переопределите его метод Execute() для поиска файлов по мере необходимости. Убедитесь, что код поиска периодически проверяет свойство TThread.Terminated и выходит из Execute(), когда установлено значение True. - person Remy Lebeau; 10.01.2012