【问题标题】:File Open Dialog with Preview in Delphi 10.3Delphi 10.3 中带有预览的文件打开对话框
【发布时间】:2020-06-10 11:06:05
【问题描述】:

我针对 Delphi 10.3 进行了更改,它的默认 TOpenDialog 包含一个预览窗格。我进行了一些搜索,发现了微软提供的IFileDialogCustomize接口,用于自定义标准WinAPI对话框。我知道我必须使用OnSelectionChange 事件处理程序来修改窗格的图片。对我来说最大的问题是:如何通过IFileDialogCustomize 访问预览窗格图像?这个 ItemID 是什么?我在网上找不到这个问题的任何答案。有人知道答案吗?然后请与我和社区分享! :)

为了简洁起见,我用 ... 替换了一些代码片段,因为这些是微不足道的或依赖于应用程序的部分。

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;

【问题讨论】:

  • 您可能已经知道这一点,但要明确一点:此对话框是标准的 Win32 打开对话框,预览窗格是其中的一部分。例如,如果您在记事本中打开“打开”对话框并按 Alt+P,则会打开预览窗格。我根本没有玩过预览窗格(尽管我用其他方式玩过这些对话框,例如在底部添加自定义控件),但我最初的猜测是应用程序不应该控制预览窗格。系统只是预览它知道如何预览的文件。我认为您可以创建自定义的此类“处理程序”。
  • 我认为没有任何 API 可以让您从对话框中获取预览图像。您可能要做的是调用 shell 扩展使用的 shell 接口来提供这些预览图像。 Raymond 称之为对界面的两侧进行编程。你想达到什么目的?提出这个问题的动机是什么?
  • @DavidHeffernan 我的老板想展示我们自己的文件格式的预览。
  • @AndreasRejbrand 是的!预览处理程序将是答案!感谢安德烈亚斯的指导!
  • “我的老板想显示我们自己的文件格式的预览。”是的,和我想的一样。在这种情况下,你不想做你在问题中概述的事情。

标签: delphi preview topendialog


【解决方案1】:

我做了一些搜索,发现了微软提供的IFileDialogCustomize接口,用于自定义标准WinAPI对话框。

首先,IFileDialogCustomize 没有“自定义标准 WinAPI 对话框”。它只自定义 IFileOpenDialogIFileSaveDialog 对话框,没有其他对话框。

其次,TOpenDialog 主要使用旧版 Win32 API GetOpenFileName() 函数。在 Windows Vista+ 上,GetOpenFileName() 在内部使用 IFileOpenDialog 并启用了基本选项,因此旧版应用程序仍然可以具有现代外观。

虽然在以下情况下,TOpenDialog 会直接使用IFileOpenDialog 而不是使用GetOpenFileName()

  • Win32MajorVersion >= 6 (Vista+)
  • UseLatestCommonDialogs 是真的
  • StyleServices.Enabled 是真的
  • TOpenDialog.Template 为零
  • TOpenDialog.OnIncludeItemTOpenDialog.OnCloseTOpenDialog.OnShow 未分配。

但即便如此,TOpenDialog 在使用时仍然无法让您访问其内部的IFileOpenDialog 接口。

如果您真的想访问对话框的IFileOpenDialogIFileDialogCustomize,您需要使用TFileOpenDialog 而不是TOpenDialog(只要知道该对话框在 XP 和更早的系统上不起作用,如果您仍然需要支持他们)。

对我来说最大的问题是:如何通过IFileDialogCustomize 访问预览窗格图像?

你没有。预览窗格不是对话框自定义,因此无法通过IFileDialogCustomize 访问。即使您可以获得预览窗格的控件 ID(您不能),也没有 IFileDialogCustomize 的功能可以让您访问预览窗格的 HWNDHDC,或以其他方式更改内容以任何方式的预览窗格。对于任何支持预览的文件类型,预览窗格是IFileDialog 不可或缺的和私有 组件。它不是您可以直接访问和利用的东西。 IFileOpenDialog 本身会在用户选择具有(或缺少)要显示的预览的文件时根据需要更新预览窗格。

我的老板想展示我们自己的文件格式的预览。

在 Vista+ 上处理该问题的正确方法是为您的自定义文件类型创建一个Preview Handler。然后,任何想要显示文件预览的 Shell 组件(包括 IFileOpenDialog)都可以使用您的处理程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多