A part of my Delphi application accesses information from another program. Because it can take some time to execute, and sometimes the other program may be unresponsive, I run that part of my code in a separate thread.
To keep my users informed of the progress of the background thread, I execute a TaskDialog after I start the thread. I pass a pointer to the TaskDialog to my thread so that the thread can synchronize with the TaskDialog to update it as the thread progresses. When the thread finishes, I send a close message to the TaskDialog using PostMessage(CurrentTaskDialog.Handle, WM_CLOSE, 0, 0);
Everything is working so far, but I want to cancel the process if the user clicks the Cancel button on the TaskDialog (it is the only button on the TaskDialog). I cannot figure-out how to do it. No matter whether the user clicks the button or if the TaskDialog receives the close message, the ModalResult
is always mrCancel
. I have tried assigning a different ModalResult
in the thread, but it still evaluates as mrCancel
.
Is there some way to accomplish this?
What you describe is normal behavior, per the
TaskDialogIndirect()
documentation:Since you only have a Cancel button, and are simulating a close button press, then
TaskDialogIndirect()
always reportsIDCANCEL
, which is why theModalResult
is alwaysmrCancel
. There is no way to differentiate the actual cause (short of hooking the dialog window itself).In any case, you don't actually need to use the
ModalResult
at all to accomplish what you want.When the dialog closes for any reason, simply signal the thread to end, and then wait for the thread to fully exit. If the thread had already ended before the dialog was closed, the signal will be ignored, and the wait will be satisfied immediately.
You could then take this a step further. Instead of using
tcbCancel
in the TaskDialog'sCommonButtons
property, you could use a custom button in the TaskDialog'sButtons
property, and then use the TaskDialog'sOnButtonClicked
event to signal the thread to exit. Block the dialog from closing automatically (by settingCanClose=False
in the event handler) and wait for the thread to close the dialog when finished. This will allow you to continue displaying feedback inside the TaskDialog while waiting for the thread to end, such as displaying a "Waiting" message. Whereas with the other approach, the TaskDialog window is closed when the user clicks on the standard Cancel button, so you can't display feedback anymore even though the thread may still be running.