简体   繁体   English

Delphi 10.3 中带预览的文件打开对话框

[英]File Open Dialog with Preview in Delphi 10.3

I changed for Delphi 10.3 and its default TOpenDialog contains a preview pane.我更改为 Delphi 10.3,其默认TOpenDialog包含一个预览窗格。 I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs.搜索了一下,找到了微软提供的IFileDialogCustomize接口,可以自定义标准的WinAPI对话框。 I know I have to use the OnSelectionChange event handler to modify the picture of the pane.我知道我必须使用OnSelectionChange事件处理程序来修改窗格的图片。 The big question for me is: how can I access the preview pane image by IFileDialogCustomize ?对我来说最大的问题是:如何通过IFileDialogCustomize访问预览窗格图像? What is the ItemID for this?这个的 ItemID 是什么? I couldn't find any answer to this question on the.net.我在 .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;

I made some searches and found the IFileDialogCustomize interface provided by Microsoft to customize standard WinAPI dialogs.搜索了一下,找到了微软提供的IFileDialogCustomize接口,可以自定义标准的WinAPI对话框。

First, IFileDialogCustomize does not "customize standard WinAPI dialogs".首先, IFileDialogCustomize不会“自定义标准 WinAPI 对话框”。 It customizes only IFileOpenDialog and IFileSaveDialog dialogs, no others.它仅自定义IFileOpenDialogIFileSaveDialog对话框,不自定义其他对话框。

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.其次, TOpenDialog主要使用遗留的 Win32 API GetOpenFileName() function。在 Windows Vista+ 上, GetOpenFileName()在内部使用启用了基本选项的IFileOpenDialog ,以便遗留应用程序仍然具有现代外观。

Although, under the following conditions, TOpenDialog will instead use IFileOpenDialog directly rather than using GetOpenFileName() :尽管在以下条件下, TOpenDialog将直接使用IFileOpenDialog而不是使用GetOpenFileName()

  • Win32MajorVersion is >= 6 (Vista+) Win32MajorVersion >= 6 (Vista+)
  • UseLatestCommonDialogs is True UseLatestCommonDialogs为真
  • StyleServices.Enabled is True StyleServices.Enabled为真
  • TOpenDialog.Template is nil TOpenDialog.Template为零
  • TOpenDialog.OnIncludeItem , TOpenDialog.OnClose , and TOpenDialog.OnShow are unassigned. TOpenDialog.OnIncludeItemTOpenDialog.OnCloseTOpenDialog.OnShow未分配。

But even so, TOpenDialog still does not give you access to its internal IFileOpenDialog interface, when it is used.但即便如此, TOpenDialog在使用时仍然不让您访问其内部IFileOpenDialog接口。

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).如果你真的想访问对话框的IFileOpenDialog和它的IFileDialogCustomize ,你需要使用TFileOpenDialog而不是TOpenDialog (只要知道对话框在 XP 和更早的系统上不起作用,如果你仍然需要支持它们的话)。

The big question for me is: how can I access the preview pane image by IFileDialogCustomize ?对我来说最大的问题是:如何通过IFileDialogCustomize访问预览窗格图像?

You don't.你不知道。 The preview pane is not a dialog customization, so it can't be accessed via IFileDialogCustomize .预览窗格不是对话框自定义,因此无法通过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.即使您可以获得预览窗格的控件 ID(您不能),也没有IFileDialogCustomize的 function 允许您访问预览窗格的HWNDHDC ,或者以其他方式更改预览窗格的内容方法。 The preview pane is an integral and private component of IFileDialog for any file type that supports previews.对于支持预览的任何文件类型,预览窗格是IFileDialog不可或缺的私有组件。 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.当用户选择具有(或缺少)要显示的预览的文件时, IFileOpenDialog本身将根据需要更新预览窗格。

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.在 Vista+ 上处理该问题的正确方法是为您的自定义文件类型创建预览处理程序。 Then, any Shell component that wants to display previews of your files, including IFileOpenDialog , can use your handler.然后,任何想要显示文件预览的 Shell 组件(包括IFileOpenDialog )都可以使用您的处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM