如果TOpenDialog包含问号,为什么会显示重复的文件过滤器掩码?

dum*_*uch 2 delphi

给出以下测试表(在Delphi 10.1和Delphi 2007中测试):

object Form1: TForm1
  Caption = 'Form1'
  ClientHeight = 340
  ClientWidth = 639
  object b_Test: TButton
    Caption = 'Test'
    OnClick = b_TestClick
  end
  object od_test: TOpenDialog
    Filter = 'blub (blub*.dbf)|blub*.dbf|bla (bla?.dbf)|bla?.dbf'
  end
end
Run Code Online (Sandbox Code Playgroud)

(我遗漏了一些默认属性,基本上它是带有TOpenDialog和按钮的表单.唯一重要的部分是TOpenDialog.Filter属性.)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    od_test: TOpenDialog;
    b_Test: TButton;
    procedure b_TestClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.b_TestClick(Sender: TObject);
begin
   od_test.Execute;
end;

end.
Run Code Online (Sandbox Code Playgroud)

为什么对话框会显示包含问号的过滤器,如下所示:

重复过滤器

这是一个已知的错误还是我做错了什么?如果这是一个已知的错误,是否有一个解决方法(除了显而易见的遗漏'(bla?.dbf)'部分描述,这意味着我必须更改所有描述.)?

编辑:这是在Windows 8.1上.我还没有尝试过其他版本.如果它有所不同:我已禁用资源管理器选项"隐藏knonw文件类型的扩展名".

Rud*_*uis 6

这里有几个因素.

因素1

正如我在评论中写的那样,我通常使用一个简单的过滤器,而不重复过滤器描述中的过滤器掩码:

OpenDialog1.Filter := 'blub|blub*.dbf|bla|bla?.dbf';
Run Code Online (Sandbox Code Playgroud)

对我来说,这会产生:

blub (blub*.dbf)
bla (bla?.dbf)
Run Code Online (Sandbox Code Playgroud)

但是,当在Windows资源管理器中,我启用文件夹选项"隐藏已知文件类型的扩展名"时,组合框的下拉列表TOpenDialog如下所示:

blub
bla
Run Code Online (Sandbox Code Playgroud)

所以现在,不再显示过滤器掩码.

因素2

为避免遗漏过滤掩码,您可以在说明中重复它,如问题所示:

OpenDialog1.Filter := 'blub (blub*.dbf)|blub*.dbf|bla (bla?.dbf)|bla?.dbf';
Run Code Online (Sandbox Code Playgroud)

如果如上所述,根据因子1的文件夹选项,是禁用(IOW,如果所有被示出的扩展),打开的对话框显然检查以查看是否该过滤器掩膜被包括在说明书中,然后将其不括号显示它再次.但这仅适用于包含星号的过滤器,但似乎不适用于包含问号的过滤器.

这就是你得到的原因:

blub (blub*.dbf)
bla (bla?.dbf) (bla?.dbf)
Run Code Online (Sandbox Code Playgroud)

禁止描述后自动显示过滤器掩码blub,但不是bla.

结论

所以ISTM你应该避免带有问号的过滤器面具,或者如果你真的必须,你不应该在描述中包括那些:

OpenDialog1.Filter := 'blub (blub*.dbf)|blub*.dbf|bla|bla?.dbf';
Run Code Online (Sandbox Code Playgroud)

但是bla,如果您的文件夹选项隐藏已知文件类型的扩展名,则存在过滤器掩码根本不显示描述的风险.那么,你的组合框下拉可能如下所示:

blub (blub*.dbf)
bla
Run Code Online (Sandbox Code Playgroud)

我想你必须做出决定.我不知道你是否或如何查询文件夹选项(这将是一个很好的新问题).如果可以,您可以提供不同的过滤字符串,具体取决于选项.

更新

根据@dummzeuch,有关该选项的信息可以在(surprise!)注册表中找到.链接:windowsitpro.com/systems-management/...

可以使用密钥HideFileExt从HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced中的注册表更改/读取此内容.当然,逻辑是相反的:设置为0以显示所有扩展,设置为1以隐藏已知扩展.


亲身,

我会继续定义简单的过滤器,比如

OpenDialog1.Filter := 'blub|blub*.dbf|bla|bla?.dbf';
Run Code Online (Sandbox Code Playgroud)

如果人们认为他们不想在他们的文件夹中看到已知的扩展名,他们将无法自动显示过滤器掩码.如果他们决定告诉Windows他们想要查看所有扩展,他们将在组合框中自动显示过滤器掩码.