2

I am trying to use the IOperationsProgressDialog component in my Windows Forms desktop application, but so far without success. I declared the following COM import types in C#...

[ComImport]
[Guid("F8383852-FCD3-11d1-A6B9-006097DF5BD4")]
internal class ProgressDialog
{
}

[ComImport]
[Guid("0C9FB851-E5C9-43EB-A370-F0677B13874C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOperationsProgressDialog
{
    ...
}

[ComImport]
[Guid("EBBC7C04-315E-11d2-B62F-006097DF5BD4")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IProgressDialog
{
    ...
}

Class- and interface-id´s are taken from shlobj.h and shobjidl.h header files from the Windows 10 SDK; so I assume they are correct. The following code allows me to create, show and update an IProgressDialog, but...

private IProgressDialog dialog;

public void Show(
    IWin32Window owner,
    string title,
    string cancelMessage)
{
    var dialog = (IProgressDialog)(new ProgressDialog());

    dialog.SetTitle(title);
    dialog.SetCancelMsg(cancelMessage, IntPtr.Zero);

    uint dwFlags = PROGDLG_NORMAL | PROGDLG_AUTOTIME;
    int hr = dialog.StartProgressDialog(owner.Handle, IntPtr.Zero, dwFlags, IntPtr.Zero);

    this.dialog = dialog;
}

public void SetProgress(ulong value, ulong total)
{
    this.dialog?.SetProgress64(value, total);
}

...it just don´t work with the IOperationsProgressDialog, which has (as I assume) the same CLSID. I´d like to use the IOperationsProgressDialog component instead of IProgressDialog since it allows the user to show more detailed information about the running operation.

private IOperationsProgressDialog dialog;

public void Show(
    IWin32Window owner)
{
    var dialog = (IOperationsProgressDialog)(new ProgressDialog());

    int hr = dialog.StartProgressDialog(owner.Handle, PROGDLG_NORMAL);

    this.dialog = dialog;
}

public void SetProgress(ulong value, ulong total)
{
    this.dialog?.UpdateProgress(0, 0, value, total, 0, 0);
}

The call to StartProgressDialog seems to work fine (the method returns S_OK), but the dialog never get´s shown and subsequent calls to other methods defined by the IOperationsProgressDialog interface result in an OutOfMemoryException.

Matze
  • 5,100
  • 6
  • 46
  • 69
  • You followed this: *The progress dialog should be created on a separate thread*, right? – rene Jun 24 '16 at 13:50
  • The creation of the `IProgressDialog` happens on the application´s main thread, but the progress is updated by a separate thread. Not sure if I can create the dialog on a separate thread, if I want make it modal... The documentation says "The progress dialog should be created on a separate thread than the file operation on which the dialog is reporting." – Matze Jun 24 '16 at 14:03
  • 2
    IOperationsProgressDialog was meant to be implemented by your own code, you use it to call IFileOperation.SetProgressDialog(). Allows you to replace, say, the pretty progress graph on the file copy dialog. The StartProgressDialog() method is supposed to be called by whatever coclass implements the IFileOperation, after it has created the dialog window. Why the cast from ProgressDialog works at all is hard to guess, it isn't documented at all. I very much doubt this is supposed to work. – Hans Passant Jun 24 '16 at 15:21
  • @HansPassant Aha... but what about this answer here: http://stackoverflow.com/questions/27506948/show-more-details-option-in-windows-vista-progress-dialog – Matze Jun 24 '16 at 16:23
  • 2
    The second screenshot is the file copy dialog I mentioned. It starts life from CLSID_FileOperation, not CLSID_ProgressDialog. – Hans Passant Jun 24 '16 at 16:37

0 Answers0