I'm running a long operation and I figured a good way to present it to the user was to use a system progress dialog using the IProgressDialog
object.
I only found a couple of usage examples, and this is my implementation. The problems I have are that the application is still irresponsive (I understand I may need to use a thread) but also the Cancel button simply doesn't work (which may be consecuence of the first issue.)
I'm using Delphi XE under Windows 8.1.
Edit: I've added an Application.ProcessMessages
call just before evaluating HasUserCancelled
but it doesn't appear to help much (dialog still doesn't process clicking on the Cancel button.)
var
i, procesados: Integer;
IDs: TList<Integer>;
pd: IProgressDialog;
tmpPtr: Pointer;
begin
procesados := 0;
try
tmpPtr := nil;
CoCreateInstance(CLSID_ProgressDialog, nil, CLSCTX_INPROC_SERVER,
IProgressDialog, pd);
// also seen as pd := CreateComObject(CLSID_ProgressDialog) as IProgressDialog;
pd.SetTitle('Please wait');
pd.SetLine(1, PWideChar(WideString('Performing a long running operation')),
false, tmpPtr);
pd.SetAnimation(HInstance, 1001); // IDA_OPERATION_ANIMATION ?
pd.Timer(PDTIMER_RESET, tmpPtr);
pd.SetCancelMsg(PWideChar('Cancelled...'), tmpPtr);
pd.StartProgressDialog(Handle, nil, PROGDLG_MODAL or
PROGDLG_NOMINIMIZE, tmpPtr);
pd.SetProgress(0, 100);
IDs := GetIDs; // not relevant, returns List<Integer>
try
for i in IDs do
begin
try
Application.ProcessMessages;
if pd.HasUserCancelled then
Break; // this never happens
Inc(procesados);
pd.SetProgress(procesados, IDs.Count);
LongRunningOp(id);
except
// ?
end;
end;
finally
IDs.Free;
end;
finally
pd.StopProgressDialog;
// pd.Release; doesn't exist
end;
end;
end;