2
votes

I changed for Delphi 10.3 and its default TOpenDialog contains a preview pane. I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs. I know I have to use the OnSelectionChange event handler to modify the picture of the pane. The big question for me is : how can I access the preview pane image by IFileDialogCustomize? What is the ItemID for this? I couldn't find any answer to this question on the net. Somebody know the answer? Then please share with me and the community! :)

I replaced some code fragments by ... for the sake of brevity, because these are trivial or app dependent sections.

procedure TMainWindow.OnSelectionChange( Sender : TObject );
var
  dc : HDC;
  aBMP : TBitmap;

  function isSelectedFilePreviewAble : boolean;
  begin
    result := ...;
  end;

  functon getPreviewPictureDC : HDC;
  var
    iCustomize : IFileDialogCustomize;
    h : THandle;
  begin
    if OpenDialog1.QueryInterface( IFileDialogCustomize, iCustomize ) = S_OK then
    begin
      h := iCustomize.??? this is the missing code fragment
      result := GetDC( h );
    end else
      result := 0;
  end;

  procedure generatePreviewPicture;  
  begin
    ...
  end;

begin
  dc := getPreviewPictureDC;
  if ( dc <> 0 ) then
  begin
    aBMP := TBitmap.Create;
    try
      if ( isSelectedFilePreviewAble ) then
        generatePreviewPicture;  
      StretchBlt( aBMP.Handle, ...);
    finally
      aBMP.Free;
      ReleaseDC( dc );
    end;    
  end;
end;
1
You probably already know this, but just to be crystal clear: this dialog is a standard Win32 open dialog, and the preview pane is part of it. For instance, if you open the "Open" dialog in Notepad and press Alt+P, the preview pane will open. I haven't played around with the preview pane at all (although I have played around with these dialogs in other ways, such as adding custom controls at the bottom), but my initial guess would be that the application shouldn't control the preview pane. The system simply previews files it knows how to preview. I think you can create custom such "handlers".Andreas Rejbrand
I don't think that there is any API for you to obtain the preview image from the dialog. What you might do is invoke the shell interfaces that are used by shell extensions to provide those preview images. What Raymond calls programming both sides of the interface. What are you trying to achieve? What motivates the question?David Heffernan
@DavidHeffernan My boss want to show previews for our own file formats.SOLID Developper
@AndreasRejbrand Yes! The Preview handler will be the answer! Thanks for the guidelines Andreas!SOLID Developper
"My boss want to show previews for our own file formats." Yeah, as I thought. You don't want to do what you outline in the question in that case.David Heffernan

1 Answers

3
votes

I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs.

First, IFileDialogCustomize does not "customize standard WinAPI dialogs". It customizes only IFileOpenDialog and IFileSaveDialog dialogs, no others.

Second, TOpenDialog primarily uses the legacy Win32 API GetOpenFileName() function. On Windows Vista+, GetOpenFileName() uses IFileOpenDialog internally with basic options enabled, so that legacy apps can still have a modern look.

Although, under the following conditions, TOpenDialog will instead use IFileOpenDialog directly rather than using GetOpenFileName():

  • Win32MajorVersion is >= 6 (Vista+)
  • UseLatestCommonDialogs is True
  • StyleServices.Enabled is True
  • TOpenDialog.Template is nil
  • TOpenDialog.OnIncludeItem, TOpenDialog.OnClose, and TOpenDialog.OnShow are unassigned.

But even so, TOpenDialog still does not give you access to its internal IFileOpenDialog interface, when it is used.

If you really want to access the dialog's IFileOpenDialog and thus its IFileDialogCustomize, you need to use TFileOpenDialog instead of TOpenDialog (just know that dialog won't work on XP and earlier systems, if you still need to support them).

The big question for me is : how can I access the preview pane image by IFileDialogCustomize?

You don't. The preview pane is not a dialog customization, so it can't be accessed via IFileDialogCustomize. Even if you could get a control ID for the preview pane (which you can't), there is no function of IFileDialogCustomize that would allow you to access the preview pane's HWND or HDC, or otherwise alter the content of the preview pane in any way. The preview pane is an integral and private component of IFileDialog for any file type that supports previews. It is not something that you can access and draw on directly. IFileOpenDialog itself will update the preview pane as needed when the user selects a file that has (or lacks) a preview to display.

My boss want to show previews for our own file formats.

The correct way to handle that on Vista+ is to create a Preview Handler for your custom file types. Then, any Shell component that wants to display previews of your files, including IFileOpenDialog, can use your handler.