delphipreviewtopendialog

File Open Dialog with Preview in Delphi 10.3


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;

Solution

  • 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():

    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.