Delphi 10.3 中带预览的文件打开对话框
File Open Dialog with Preview in Delphi 10.3
我针对 Delphi 10.3 进行了更改,其默认 TOpenDialog
包含一个预览窗格。我进行了一些搜索,找到了 Microsoft 提供的用于自定义标准 WinAPI
对话框的 IFileDialogCustomize
界面。我知道我必须使用 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;
I made some searches and found the IFileDialogCustomize
interface provided by Microsoft to customize standard WinAPI dialogs.
首先,IFileDialogCustomize
不是"customize standard WinAPI dialogs"。它仅自定义 IFileOpenDialog
和 IFileSaveDialog
对话框,不自定义其他对话框。
二、TOpenDialog
primarily uses the legacy Win32 API GetOpenFileName()
函数。在 Windows Vista+ 上,GetOpenFileName()
在内部使用 IFileOpenDialog
并启用了基本选项,因此旧版应用程序仍然可以拥有现代外观。
虽然,在以下条件下,TOpenDialog
会直接使用IFileOpenDialog
,而不是使用GetOpenFileName()
:
Win32MajorVersion
是 >= 6 (Vista+)
UseLatestCommonDialogs
为真
StyleServices.Enabled
为真
TOpenDialog.Template
为零
TOpenDialog.OnIncludeItem
、TOpenDialog.OnClose
和 TOpenDialog.OnShow
未分配。
但即便如此,TOpenDialog
仍然不允许您在使用时访问其内部 IFileOpenDialog
界面。
如果你真的想访问对话框的 IFileOpenDialog
并因此访问它的 IFileDialogCustomize
,你需要使用 TFileOpenDialog
而不是 TOpenDialog
(只知道对话框不会'不能在 XP 和更早的系统上工作,如果您仍然需要支持它们的话)。
The big question for me is : how can I access the preview pane image by IFileDialogCustomize
?
你不知道。预览窗格不是对话框自定义,因此无法通过 IFileDialogCustomize
访问。即使您可以获得预览窗格的控件 ID(您不能),IFileDialogCustomize
也没有允许您访问预览窗格的 HWND
或 HDC
的功能,或以任何方式更改预览窗格的内容。对于支持预览的任何文件类型,预览窗格是 IFileDialog
不可或缺的 和私有 组件。它不是您可以直接访问和利用的东西。 IFileOpenDialog
当用户选择具有(或缺少)要显示的预览的文件时,它本身将根据需要更新预览窗格。
My boss want to show previews for our own file formats.
在 Vista+ 上正确的 处理方法是为您的自定义文件类型创建 Preview Handler。然后,任何 Shell 想要显示文件预览的组件,包括 IFileOpenDialog
,都可以使用您的处理程序。
我针对 Delphi 10.3 进行了更改,其默认 TOpenDialog
包含一个预览窗格。我进行了一些搜索,找到了 Microsoft 提供的用于自定义标准 WinAPI
对话框的 IFileDialogCustomize
界面。我知道我必须使用 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;
I made some searches and found the
IFileDialogCustomize
interface provided by Microsoft to customize standard WinAPI dialogs.
首先,IFileDialogCustomize
不是"customize standard WinAPI dialogs"。它仅自定义 IFileOpenDialog
和 IFileSaveDialog
对话框,不自定义其他对话框。
二、TOpenDialog
primarily uses the legacy Win32 API GetOpenFileName()
函数。在 Windows Vista+ 上,GetOpenFileName()
在内部使用 IFileOpenDialog
并启用了基本选项,因此旧版应用程序仍然可以拥有现代外观。
虽然,在以下条件下,TOpenDialog
会直接使用IFileOpenDialog
,而不是使用GetOpenFileName()
:
Win32MajorVersion
是 >= 6 (Vista+)UseLatestCommonDialogs
为真StyleServices.Enabled
为真TOpenDialog.Template
为零TOpenDialog.OnIncludeItem
、TOpenDialog.OnClose
和TOpenDialog.OnShow
未分配。
但即便如此,TOpenDialog
仍然不允许您在使用时访问其内部 IFileOpenDialog
界面。
如果你真的想访问对话框的 IFileOpenDialog
并因此访问它的 IFileDialogCustomize
,你需要使用 TFileOpenDialog
而不是 TOpenDialog
(只知道对话框不会'不能在 XP 和更早的系统上工作,如果您仍然需要支持它们的话)。
The big question for me is : how can I access the preview pane image by
IFileDialogCustomize
?
你不知道。预览窗格不是对话框自定义,因此无法通过 IFileDialogCustomize
访问。即使您可以获得预览窗格的控件 ID(您不能),IFileDialogCustomize
也没有允许您访问预览窗格的 HWND
或 HDC
的功能,或以任何方式更改预览窗格的内容。对于支持预览的任何文件类型,预览窗格是 IFileDialog
不可或缺的 和私有 组件。它不是您可以直接访问和利用的东西。 IFileOpenDialog
当用户选择具有(或缺少)要显示的预览的文件时,它本身将根据需要更新预览窗格。
My boss want to show previews for our own file formats.
在 Vista+ 上正确的 处理方法是为您的自定义文件类型创建 Preview Handler。然后,任何 Shell 想要显示文件预览的组件,包括 IFileOpenDialog
,都可以使用您的处理程序。