如何使用Delphi从文件扩展名中获取图标和描述?

基本上我有一个TcxGrid这将列出各种文件的名称,我想进一步的细节基础上的文件扩展名,特别是它的描述(例如.PDF它是“Adobe Acrobat文档”)和它的相关图标

我注意到已经有一个非常类似的问题,但它是C#相关的,我想要一些基于Delphi的东西。

build议在哪里寻找这种信息将是很好的,如果有一个类似于上面提到的C#职位(显然是在Delphi中),这将是伟大的。

Solutions Collecting From Web of "如何使用Delphi从文件扩展名中获取图标和描述?"

感谢Rob Kennedy指点我ShGetFileInfo的方向。 然后我搜索了这个,发现了这两个例子 – 德尔福3000 , 托里的 。 从那我写了下面的课,做我所需要的。

另外,正如我在完成比尔·米勒的回答给了我需要的最后一点帮助。 本来我是通过完整的文件名通过ShGetFileInfo,这不是我想要的理想。 传递“* .EXT”的建议很好。

班上可以做更多的工作,但它做我所需要的。 它似乎处理没有任何细节相关的文件扩展名。

最后,在我正在使用的我已经切换到使用TcxImageList而不是TImageList,因为我有问题与图标上出现的黑色边框,因为这是一个快速修复。

unit FileAssociationDetails; { Created : 2009-05-07 Description : Class to get file type description and icons. * Extensions and Descriptions are held in a TStringLists. * Icons are stored in a TImageList. Assumption is all lists are in same order. } interface uses Classes, Controls; type TFileAssociationDetails = class(TObject) private FImages : TImageList; FExtensions : TStringList; FDescriptions : TStringList; public constructor Create; destructor Destroy; override; procedure AddFile(FileName : string); procedure AddExtension(Extension : string); procedure Clear; procedure GetFileIconsAndDescriptions; property Images : TImageList read FImages; property Extensions : TStringList read FExtensions; property Descriptions : TStringList read FDescriptions; end; implementation uses SysUtils, ShellAPI, Graphics, Windows; { TFileAssociationDetails } constructor TFileAssociationDetails.Create; begin try inherited; FExtensions := TStringList.Create; FExtensions.Sorted := true; FDescriptions := TStringList.Create; FImages := TImageList.Create(nil); except end; end; destructor TFileAssociationDetails.Destroy; begin try FExtensions.Free; FDescriptions.Free; FImages.Free; finally inherited; end; end; procedure TFileAssociationDetails.AddFile(FileName: string); begin AddExtension(ExtractFileExt(FileName)); end; procedure TFileAssociationDetails.AddExtension(Extension : string); begin Extension := UpperCase(Extension); if (Trim(Extension) <> '') and (FExtensions.IndexOf(Extension) = -1) then FExtensions.Add(Extension); end; procedure TFileAssociationDetails.Clear; begin FExtensions.Clear; end; procedure TFileAssociationDetails.GetFileIconsAndDescriptions; var Icon: TIcon; iCount : integer; Extension : string; FileInfo : SHFILEINFO; begin FImages.Clear; FDescriptions.Clear; Icon := TIcon.Create; try // Loop through all stored extensions and retrieve relevant info for iCount := 0 to FExtensions.Count - 1 do begin Extension := '*' + FExtensions.Strings[iCount]; // Get description type SHGetFileInfo(PChar(Extension), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES ); FDescriptions.Add(FileInfo.szTypeName); // Get icon and copy into ImageList SHGetFileInfo(PChar(Extension), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES ); Icon.Handle := FileInfo.hIcon; FImages.AddIcon(Icon); end; finally Icon.Free; end; end; end. 

另外这里是一个使用它的示例测试应用程序,它非常简单,只是一个带有TPageControl的窗体。 我的实际使用不是为了这个,而是使用TcxGrid中的Developer Express TcxImageComboxBox。

 unit Main; { Created : 2009-05-07 Description : Test app for TFileAssociationDetails. } interface uses Windows, Forms, FileAssociationDetails, Classes, Controls, ComCtrls; type TfmTest = class(TForm) PageControl1: TPageControl; procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } FFileDetails : TFileAssociationDetails; public { Public declarations } end; var fmTest: TfmTest; implementation {$R *.dfm} procedure TfmTest.FormShow(Sender: TObject); var iCount : integer; NewTab : TTabSheet; begin FFileDetails := TFileAssociationDetails.Create; FFileDetails.AddFile('C:\Documents and Settings\...\Test.XLS'); FFileDetails.AddExtension('.zip'); FFileDetails.AddExtension('.pdf'); FFileDetails.AddExtension('.pas'); FFileDetails.AddExtension('.XML'); FFileDetails.AddExtension('.poo'); FFileDetails.GetFileIconsAndDescriptions; PageControl1.Images := FFileDetails.Images; for iCount := 0 to FFileDetails.Descriptions.Count - 1 do begin NewTab := TTabSheet.Create(PageControl1); NewTab.PageControl := PageControl1; NewTab.Caption := FFileDetails.Descriptions.Strings[iCount]; NewTab.ImageIndex := iCount; end; end; procedure TfmTest.FormClose(Sender: TObject; var Action: TCloseAction); begin PageControl1.Images := nil; FFileDetails.Free; end; end. 

感谢大家的答复!

 function GetGenericFileType( AExtension: string ): string; { Get file type for an extension } var AInfo: TSHFileInfo; begin SHGetFileInfo( PChar( AExtension ), FILE_ATTRIBUTE_NORMAL, AInfo, SizeOf( AInfo ), SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES ); Result := AInfo.szTypeName; end; function GetGenericIconIndex( AExtension: string ): integer; { Get icon index for an extension type } var AInfo: TSHFileInfo; begin if SHGetFileInfo( PChar( AExtension ), FILE_ATTRIBUTE_NORMAL, AInfo, SizeOf( AInfo ), SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES ) <> 0 then Result := AInfo.iIcon else Result := -1; end; function GetGenericFileIcon( AExtension: string ): TIcon; { Get icon for an extension } var AInfo: TSHFileInfo; AIcon: TIcon; begin if SHGetFileInfo( PChar( AExtension ), FILE_ATTRIBUTE_NORMAL, AInfo, SizeOf( AInfo ), SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES ) <> 0 then begin AIcon := TIcon.Create; try AIcon.Handle := AInfo.hIcon; Result := AIcon; except AIcon.Free; raise; end; end else Result := nil; end; 

调用ShGetFileInfo 它可以告诉你这个描述(这个函数的词汇表中的“类型名称”),它可以给你一个图标句柄,或者一个系统图像列表的句柄,图标所在的位置,或者模块的路径图像资源。 该功能可以做很多不同的事情,所以一定要仔细阅读文档。

MSDN说 ShGetFileInfo “可能会很慢”,并调用IExtractIcon接口“更灵活和高效”的选择。 但它推荐的顺序是使用一个IShellFolder接口,然后调用GetUIObjectOf来获取文件的IExtractIcon接口,然后调用GetIconLocationExtract来检索图标的句柄。

对于我所知道的,这正是ShGetFileInfo所做的,但是更麻烦一些,在完成之后,你仍然没有文件的类型描述。 坚持ShGetFileInfo直到速度和效率成为一个明显的问题。

 uses ShellAPI; var AExtension: string; AFileType: string; AListItem: TListItem; AFileInfo: TSHFileInfo; begin // get the extensions file icon AExtension := ExtractFileExt( FileName ); if SHGetFileInfo( PChar( '*' + AExtension ), FILE_ATTRIBUTE_NORMAL, AFileInfo, SizeOf ( AFileInfo ), SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES ) <> 0 then AIndex := AFileInfo.iIcon else AIndex := -1; AListItem.ImageIndex := AIndex; // get extensions file info if SHGetFileInfo( PChar( '*' + AExtension ), FILE_ATTRIBUTE_NORMAL, Info, SizeOf( Info ), SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES ) then AFileType := AFileInfo.szTypeName; end; 

不要听起来滑稽,但Google是你的朋友。 这里有几个“delphi相关图标”的第一个结果:

http://www.delphi3000.com/articles/article_453.asp?SK=

sof/windows/www.jpgriffiths.com/tutorial/Snippets%5Cgetassociatedicon.html

另一种方法是在HKEY_CLASSES_ROOT下查找注册表中的扩展名,然后按照默认值(如果可用)中的键,其默认值是描述。 第二个级别也是您可以打开shell命令的位置,或者打印文件类型以及默认图标的路径。

这里有几个使用bitwisemag.com的ShGetFileInfo的很好的例子:

http://www.bitwisemag.com/copy/delphi/lpad1.html

http://www.bitwisemag.com/copy/delphi/prog_groups2.html