0

我在文件打开对话框上有一个过滤器

  Docs := 'Indscannet fil (*.jpg)|*.jpg|Indscannet fil (*.tif)|*.tif|' +
          'Word 2007 dokument (*.docx)|*.docx|Word 2003 dokument (*.doc)|*.doc|' +
          'PDF fil (*.pdf)|*.pdf|Alle filer (*.*)|*.*';

当我选择了一个文件,假设它被称为 stack.pdf,我想知道它是类型 5 (jpg=1, tif=2, docx=3, doc=4, pdf=5)

如何以最简单的方式做到这一点?

这一切的原因是用户几乎总是添加几个相同类型的文档,如果这是一个 PDF,我知道我的过滤器中的编号为 5,下次用户添加文件时,我可以将 dlgOpen.FilterIndex 设置为 5e开始,这样他们就不必每次都选择它。如果是 20 个文档,它可能会节省几分钟。

4

3 回答 3

2

更新:正如@David Heffernan 在下面的评论中提到的,FilterIndex并不总是与实际的文件扩展名匹配;所以你不应该使用FilterIndex来确定文件类型。因此,您必须提取文件扩展名并使用它;

您可以定义已知的文件类型枚举,例如:

TKnowFiles = (kfUnknown, kfJpg, kfTif, ...) 

你也可以定义他们的名字,比如

const FilterNames = array[TKnownFiles] of string = ('Any file', ...); 

然后您可以使用 RTTI 函数getEnumName/getEnumValue转换kfJpg为字符串表示形式并在运行时构建Filter字符串。还使用枚举允许您轻松维护和扩展您的代码(如果您必须在下周在 tif 和 docx 之间插入 BMP 文件怎么办?docx、doc、pdf 变成 4、5、6 而不是 3、4、5 并且您可以编辑您的代码。)
可能的解决方案之一是:

type
    TKnownFileTypes = (kftUnknown, kftJpg, kftTif, kftDocx, kftDoc, kftPdf);
const
    FileFilterNames : array[TKnownFileTypes] of string = (
                            'Alle filer',
                            'Indscannet fil',
                            'Indscannet fil',
                            'Word 2007 dokument',
                            'Word 2003 dokument',
                            'PDF fil');

procedure TForm4.Button1Click(Sender: TObject);
const KnownFiles = [low(TKnownFileTypes) .. high(TKnownFileTypes)];
var filterString : string;
    fext : string;
    kf : TKnownFileTypes;
    kfs : string;

    resultFileType : TKnownFileTypes;
begin
    for kf in KnownFiles - [kftUnknown] do begin
        kfs := getEnumName(typeinfo(TKnownFileTypes), ord(kf));
        Delete(kfs, 1, 3);
        LowerCase(kfs);

        FilterString := FilterString +
                        Format('%s (*.%s)|*.%s|', [FileFilterNames[kf], kfs, kfs]);

    end;
    FilterString := FilterString + Format('%s (*.*)|*.*', [FileFilterNames[kftUnknown]]);
    OpenDialog1.Filter := FilterString;

    if not OpenDialog1.Execute() then exit;

    fext := ExtractFileExt(OpenDialog1.FileName);
    Delete(fext, 1,1); //delete .dot
    fext := 'kft' + fExt;

    resultFileType := kftUnknown;
    for kf in KnownFiles - [kftUnknown] do begin
        kfs := getEnumName(typeinfo(TKnownFileTypes), ord(kf));
        kfs := LowerCase(kfs);
        if kfs <> fext then continue;

        resultFileType := kf;
    end;

    ShowMessage(Format('File Type: %s', [FileFilterNames[resultFileType]]));
end;
于 2012-05-25T08:15:58.220 回答
1

您可以使用ExtractFileExt从完整路径中提取文件扩展名。

或使用openDialog.FilterIndex属性来获取所选过滤器的索引(在您的情况下为 pdf 为 5)。

于 2012-05-25T06:52:25.387 回答
0

我的解决方案是

function ExtensionIndex(const aFilter, aFile: string): integer;
var
  List: TStringList;
  Buffer: TStringList;
  i: Integer;
  Key: string;
  fExt: string;
begin
  Result := - 1;
  i := 0;
  List := TStringList.Create;
  List.LineBreak := '|';
  List.Text := aFilter;
  Buffer := TStringList.Create;
  Buffer.Sorted := False;
  try
    while i < List.Count do
      begin
        inc(i);
        Key := AnsiLowerCase(List[i]);
        inc(i);
        Buffer.Add(Key);
      end;
    fExt := AnsiLowerCase(ExtractFileExt(aFile));
    for i := 0 to Buffer.Count - 1 do
      if Buffer[i] = '*' + fExt  then
        begin
          Result := i + 1;
          exit;
      end;
  finally
    FreeAndNil(Buffer);
    FreeAndNil(List);
  end;
end;

这对我有用。

于 2012-05-31T15:30:12.133 回答