C++ Builder TOpenDialog - 如何增加所选文件数量的限制?

问题描述 投票:0回答:1

我遇到了一个问题,对话框中可以打开的文件数量限制为大约 600 个。当选择超过此数量时,对话框底部的编辑框会变为空,并且不会打开任何文件。

需要使用应用程序打开的文件具有相对较长的名称(70+个字符),这无疑是一个因素,但无法更改。该应用程序需要能够打开超过 5000 个文件。

问题是,限制在哪里/如何定义,是否可以增加?如果是的话,怎么办?

据我所知,这不是其他人为 C++Builder 报告的问题。我确实找到了一篇与 Delphi 相关的帖子,也有同样的问题,但建议的解决方案(增加全局变量

OpenDialogMaxMultiSelFiles
)不适用于 C++Builder,因为我在任何地方都找不到对它的任何引用。

c++builder vcl topendialog
1个回答
0
投票

旧版

TOpenDialog
VCL 组件是 Win32
GetOpenFileName()
IFileOpenDialog
API 的包装器。它内部使用哪个 API 取决于各种标准。

如果满足以下条件全部,则会使用

IFileOpenDialog

  • Windows版本为Vista或更高版本。
  • 全局变量
    Vcl.Dialogs.UseLatestCommonDialogs
    True
    (默认情况下)。
  • 自定义 VCL 样式未激活,或者
    shDialogs
    中未启用
    TStyleManager.SystemHooks
    标志。
  • Win32 视觉样式已启用(即,应用程序清单启用
    Comctl32.dll
    v6,并且
    IsAppThemed()
    返回
    true
    )。
  • Template
    属性是
    nil
  • OnIncludeItem
    OnClose
    OnShow
    事件没有分配给它们的处理程序。

如果不满足其中任何一个条件,

TOpenDialog
将使用
GetOpenFileName()
代替。

TOpenDialog
使用
GetOpenFileName()
时,它使用固定大小的字符缓冲区从API接收选定的文件名。当启用
ofAllowMultiSelect
标志时,该缓冲区的大小最多为 65519 个字符,并且 API 将使用父目录的完整路径填充它,后跟该目录中所选文件名的列表。当选择的文件超过 600 个时,该缓冲区很容易耗尽。并且没有选项可以根据选择的文件数量动态分配该缓冲区,必须在调用 API 时预先提供该缓冲区。因此,增加此限制的唯一方法(无需修改 VCL 的源代码)就是简单地自己调用
GetOpenFileName()
,为其提供更大的缓冲区来使用,即 1.5-2MB 就足够了。

TOpenDialog
使用
IFileOpenDialog
时,它会从 API 接收单个
IShellItemArray
,该 API 提供对
IShellItem
数组的枚举,每个选定文件对应一个。每个完整的文件路径+名称都是从每个
IShellItem
动态检索的。因此,这种方法应该仅受可用内存的限制。

如果您想强制执行

IFileOpenDialog
行为,则可以使用
TFileOpenDialog
组件。只要知道它不适用于 Vista 之前的 Windows 版本(如果您需要的话)。

© www.soinside.com 2019 - 2024. All rights reserved.