1

I can not find an example of using TTaskDialog in Delphi to show a progress bar. The Embarcadero docs are not helpful at all as far as TTaskDialog is concerned.

The best guide I found:

http://specials.rejbrand.se/TTaskDialog

doesn't contain any sample for showing a progress bar.

I can see various flags in the Delphi source for progress bar but in order to try them out, I have no idea how the task dialog can be displayed modeless to experiment with the flags.

Update: I have come to the conclusion that the task dialog can not be used in the traditional way that modeless progress dialogs are used. Here is what I usually do for long running operations:

show progress dialog modeless
start a loop to do work
  ... update progress bar in above dialog (often on a modulo count)
  ... check for cancel and abort if needed
remove progress dialog

My experiments with TTaskDialog based on an answer by bummi show the following:

  • Timer event does not help for updates to the progress bar. The event gets fired but any updates to the progress bar in the timer event do not show up even with updatewindow call.
  • The dialog can not be started modeless so even if the timer event is somehow made to update the progressbar, the logic has to change considerably to proceed with work in the timer event.
  • The only way progress bar position can be shown is to set it before execute. In that sense, it works exactly as described in the answer by SilverWarior. Its likely use seems to be, show in a looping operation with a new progressbar position, only when you need to get the next button response from the user. So that seems to be the correct answer but I will wait for more responses to this update.

P.S. I used Delphi 2007 for this test. So I don't know if the progress bar updates from timer work for a later IDE. But I doubt it because even the D2007 code internally sends standard TaskDialog message to update the progress bar.

user173399
  • 464
  • 5
  • 21
  • TaskDialog isn't a progress dialog. It is documented on msdn. – David Heffernan Nov 02 '14 at 04:03
  • 1
    @David, do you have a link? – Uli Gerhardt Nov 02 '14 at 10:20
  • http://msdn.microsoft.com/en-us/library/windows/desktop/bb760544(v=vs.85).aspx – David Heffernan Nov 02 '14 at 12:48
  • 1
    Please see: http://msdn.microsoft.com/en-us/library/windows/desktop/hh298380%28v=vs.85%29.aspx. This shows that TaskDialogIndirect can be used to show a progress bar. – user173399 Nov 02 '14 at 13:04
  • Oops. How do I add a new line to a comment? If you see my original link posted, it suggests at the end that progressbar is possible and the author had a plan to document it. – user173399 Nov 02 '14 at 13:06
  • Tested with D2007,D2010,XE,XE3. If you follow up execute in `Dialogs.pas` you will find `TaskDialogIndirect` is already used. `TCustomTaskDialog.DoExecute` `Result := TaskDialogIndirect(...` – bummi Nov 03 '14 at 08:41
  • @David, I understood you're comment as "It is documented on MSDN that TaskDialog isn't a progress dialog". I can't find that - not on the page you linked (which I looked into **before** I asked, of course :-)) nor on a few other related pages. – Uli Gerhardt Nov 03 '14 at 09:14
  • @Uli The two sentences weren't meant to be linked. The second sentence is a statement of fact. Documentation exists. Of course, you can make the dialog display progress but I don't think that's its primary design. – David Heffernan Nov 03 '14 at 13:55
  • @Uli The two sentences weren't meant to be linked. The second sentence is a statement of fact. Documentation exists. Of course, you can make the dialog display progress but I don't think that's its primary design. – David Heffernan Nov 03 '14 at 13:56

1 Answers1

3

If you add tfCallbackTimer to the Flags the OnTimer- Event will be triggered 5 times per second.
Since the dialog is blocking a use case could be having a thread copying files with a tread save property for the progress.
Within the timer you are able to reflect the current progress.

enter image description here

begin
  TaskDialog1.ProgressBar.Min := 0;
  TaskDialog1.ProgressBar.Max := 100;
  TaskDialog1.Execute;
end;

procedure TMyForm.TaskDialog1Timer(Sender: TObject; TickCount: Cardinal; var Reset: Boolean);
begin
   // TaskDialog1.ProgressBar.Position := MyThread.CurrentProgressPercent;
   // Demo
   TaskDialog1.ProgressBar.Position :=  TaskDialog1.ProgressBar.Position + 1;
end;
bummi
  • 27,123
  • 14
  • 62
  • 101
  • Have you actually tried the above? I tried it and setting the position doesn't change anything. Only if I set position before Execute, it shows it with animation when executed. I'll try more when I get time. – user173399 Nov 03 '14 at 01:57
  • I'll have to verify if there is some special problem with D2007 later in the office. From the behavior described in your extended question it looks like your work loop is blocking, that's why my answer was talking about a thread with a thread save property, did you verify with a vanilla project as shown in my answer? – bummi Nov 03 '14 at 06:51
  • Oops. I didn't pay real attention to your blocking and thread note. That could be it. I will try to make a small project. Thanks. – user173399 Nov 03 '14 at 14:35