查找字符串的索引

时间:2012-05-25 06:45:09

标签: string delphi search

我在fileopen对话框上有一个过滤器

  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)< / p>

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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

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

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

然后您可以使用RTTI函数getEnumName/getEnumValuekfJpg转换为字符串表示形式,并在运行时构建Filter字符串。 同样使用枚举可以让你轻松维护和扩展你的代码(如果你必须在下周的tif和docx之间插入BMP文件怎么办?docx,doc,pdf becoome 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;

答案 1 :(得分:1)

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

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

答案 2 :(得分: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;

这对我有用。