2

I have a standard Find Dialog:

enter image description here

My program can process some very large files, and finding text in such files may take 10 or 20 seconds or more. So after the "Find Next" button is pressed, I change the cursor to an hourglass. I change it back to the standard pointer after the text is either found or not found.

My problem is that the user may decide to cancel the search and decide to do so by pressing the Cancel button. The Cancel button then closes the dialog but the search continues within my FindDialogFind routine until the text is either found or not found.

I've put a breakpoint upon exit from the FindDialog.exe, but it is not reached until the FindDialogFind is completed.

Is there any way I can capture the fact that the Cancel button has been pressed which will allow me to break the FindDialogFind loop, or maybe is there some better way to stop the search when the Cancel button is pressed?

menjaraz
  • 7,551
  • 4
  • 41
  • 81
lkessler
  • 19,819
  • 36
  • 132
  • 203
  • In the `OnClose` event of the `FindDialog`, set a boolean variable, `FStopSearch`. Check this var often in your search routine, and abort search if set. – LU RD Jan 09 '12 at 06:30
  • 2
    @LURD - That's exactly what I'd like to do. How do I set up an OnClose event handler for a Windows common dialog? It is not a Delphi form. And why don't you give this to me as an answer, rather than a comment? – lkessler Jan 09 '12 at 06:58
  • Whoops. The FindDialog dropped on does have three events. FindDialogClose should work fine. Thanks. We all have those days when nothing registers. Sorry. – lkessler Jan 09 '12 at 07:04
  • Ok, I made an answer of it, and added a comment about the TFindDialog component. – LU RD Jan 09 '12 at 07:05

2 Answers2

4

In the OnCloseevent of the TFindDialog component, set a boolean variable, FAbortSearch. Check this var often in your search routine, and abort if set.

LU RD
  • 34,438
  • 5
  • 88
  • 296
  • That will, of course, only work if the search routine is calling `Application.ProcessMessages()` periodically so the Cancel button will work at all. – Remy Lebeau Jan 09 '12 at 22:10
1

Move the searching logic into a worker thread that you launch whenever the Next button is pressed. When the dialog is closed, you can terminate the thread if it is still running.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I could, but no real need to since this becomes the primary task the user is waiting for. – lkessler Jan 09 '12 at 23:35
  • Perhaps, but it does allow you to cancel the search operation cleanly, without slowing down the search itself, or introducing side effects, by calling `Application.ProcessMessages()` during the searching so the dialog remains responsive to user input. Any time you have to block the main thread for any noticable amount of time, you should consider using a worker thread. The main thread needs to remain responsive to the message queue in a timely manner. – Remy Lebeau Jan 09 '12 at 23:40
  • ... if only Delphi made threading easier. Please pass it on Remy. – lkessler Jan 10 '12 at 02:03
  • It does. Derive a class from `TThread`. Add parameters to its constructor to pass in your search criteria, and override its `Execute()` method to search the files as needed. Make sure to have the search code check the `TThread.Terminated` property periodically and exit from `Execute()` when set to True. – Remy Lebeau Jan 10 '12 at 02:28