English 中文(简体)
查找字符串索引
原标题:Finding the index of a string

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

  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 (*.*)|*.* ;

当我选择一个文件时, 可以说它叫堆叠.pdf, 我想知道它是5型(jpg=1, tif=2, docx=3, doc=3, doc=4, pdf=5)

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

之所以如此,是因为用户几乎总是会添加相同类型的若干文档,如果这是一个PDF,我知道这在我的过滤器中是5号,下次用户会添加一个文件,我就可以从一开始就设置 dlg Open.FilterIndex 到 5e, 这样他们就不必每次选择它。 如果是20个文档, 它可能省下几个小字节。

问题回答

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

您可以定义已知的文件类型计数, 如 :

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

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

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

then you can use RTTI functions getEnumName/getEnumValue to convert kfJpg to string representation and build Filter string at runtime. also using enumeration allows you to easily maintain and extend your code (what if you have to insert BMP files between tif and docx next week? docx, doc,pdf becoome 4,5,6 instead of 3,4,5 and you sould edit your code. )
one of possible solutions is:

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;

我的解决方案是

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;

这招对我有好处





相关问题
Simple JAVA: Password Verifier problem

I have a simple problem that says: A password for xyz corporation is supposed to be 6 characters long and made up of a combination of letters and digits. Write a program fragment to read in a string ...

Case insensitive comparison of strings in shell script

The == operator is used to compare two strings in shell script. However, I want to compare two strings ignoring case, how can it be done? Is there any standard command for this?

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

String initialization with pair of iterators

I m trying to initialize string with iterators and something like this works: ifstream fin("tmp.txt"); istream_iterator<char> in_i(fin), eos; //here eos is 1 over the end string s(in_i, ...

break a string in parts

I have a string "pc1|pc2|pc3|" I want to get each word on different line like: pc1 pc2 pc3 I need to do this in C#... any suggestions??

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签