当任何TGraphic后代使用类过程TPicture.RegisterFileFormat()注册自己的图形文件格式时,它们都存储在Graphics.FileFormats全局变量中。
太糟糕了,FileFormats变量不在“Graphics.pas”的“interface”部分,所以我无法访问它。我需要读取这个变量来为我的文件列表控件实现一个特殊的过滤器。
我可以在没有手动修复Graphics.pas的源代码的情况下获得该列表吗?
解决方法
您正在使用文件列表控件,大概是文件名列表。如果您不需要知道已注册的实际TGraphic类类型,只需要注册一个给定的文件扩展名(例如,检查以后调用TPicture.LoadFromFile()是否可能成功),您可以使用public GraphicFileMask()函数获取已注册文件扩展名的列表,然后将您的文件名与该列表进行比较。例如:
uses SysUtils,Classes,Graphics,Masks; function IsGraphicClassRegistered(const FileName: String): Boolean; var Ext: String; List: TStringList; I: Integer; begin Result := False; Ext := ExtractFileExt(FileName); List := TStringList.Create; try List.Delimiter := ';'; List.StrictDelimiter := True; List.DelimitedText := GraphicFileMask(TGraphic); for I := 0 to List.Count-1 do begin if MatchesMask(FileName,List[I]) then begin Result := True; Exit; end; end; finally List.Free; end; end;
或者,您可以简单地加载文件,看看会发生什么:
uses Graphics; function GetRegisteredGraphicClass(const FileName: String): TGraphicClass; var Picture: TPicture; begin Result := nil; try Picture := TPicture.Create; try Picture.LoadFromFile(FileName); Result := TGraphicClass(Picture.Graphic.ClassType); finally Picture.Free; end; except end; end;
更新:如果要解压扩展和描述,可以使用TStringList.DelimitedText解析GraphicFilter()函数的结果:
uses SysUtils,Graphics; function RPos(const ASub,AIn: String; AStart: Integer = -1): Integer; var i: Integer; LStartPos: Integer; LTokenLen: Integer; begin Result := 0; LTokenLen := Length(ASub); // Get starting position if AStart < 0 then begin AStart := Length(AIn); end; if AStart < (Length(AIn) - LTokenLen + 1) then begin LStartPos := AStart; end else begin LStartPos := (Length(AIn) - LTokenLen + 1); end; // Search for the string for i := LStartPos downto 1 do begin if Copy(AIn,i,LTokenLen) = ASub then begin Result := i; Break; end; end; end; procedure GetRegisteredGraphicFormats(AFormats: TStrings); var List: TStringList; i,j: Integer; desc,ext: string; begin List := TStringList.Create; try List.Delimiter := '|'; List.StrictDelimiter := True; List.DelimitedText := GraphicFilter(TGraphic); i := 0; if List.Count > 2 then Inc(i,2); // skip the "All" filter ... while i <= List.Count-1 do begin desc := List[i]; ext := List[i+1]; j := RPos('(',desc); if j > 0 then desc := TrimRight(Copy(desc,1,j-1)); // remove extension mask from description AFormats.Add(ext + '=' + desc); Inc(i,2); end; finally List.Free; end; end;
更新2:如果您只对注册的图形文件扩展名单感兴趣,则假设List是已创建的TStrings后代,请使用以下命令:
ExtractStrings([';'],['*','.'],PChar(GraphicFileMask(TGraphic)),List);