Hanlin
Hanlin

Reputation: 855

How to get a font file icon?

I can get font folder icon like this :

var
sfi : SHFILEINFO;
begin
  SHGetFileInfo('C:\Windows\Fonts\Arial' , 0 , sfi , SizeOf(sfi) , SHGFI_ICON);
  Image1.Picture.Icon.Handle := sfi.hIcon;
end;

but fail like this :

var
sfi : SHFILEINFO;
begin
  SHGetFileInfo('C:\Windows\Fonts\ARIALN.TTF' , 0 , sfi , SizeOf(sfi) , SHGFI_ICON);  
  Image1.Picture.Icon.Handle := sfi.hIcon;
end;

it seem like can't get font file's icon but can get font folder , I wonder how to get a font file icon ?

Upvotes: 0

Views: 1046

Answers (2)

Hanlin
Hanlin

Reputation: 855

Use Windows Shell to get font file icon :

Code :

var
  psfDeskTop : IShellFolder;
  psfFont : IShellFolder;
  pEnumList : IEnumIdList;
  pidFont : PItemIdList;
  pidChild : PItemIdList;
  FontPath : array[0..MAX_PATH - 1] of Char;
  IconFile : array[0..MAX_PATH - 1] of Char;
  pchEaten, dwAttributes, ItemsFetched : ULONG;
  ExtractIcon : IExtractIcon;
  IconIndex : Integer;
  Flags : DWORD;
  Icon : TIcon;
  LH, SH : HICon;
begin
  FillChar(FontPath, sizeof(FontPath), #0);
  //get C:\Windows\Fonts
  SHGetSpecialFolderPath(0, FontPath, CSIDL_FONTS, False);
  SHGetDesktopFolder(psfDeskTop);
  psfDeskTop.ParseDisplayName(0, nil, FontPath, pchEaten, pidFont,
    dwAttributes);
  //get font folder's interface
  psfDeskTop.BindToObject(pidFont, nil, IID_IShellFolder, psfFont);
  //Enumerate
  psfFont.EnumObjects(0, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or
    SHCONTF_INCLUDEHIDDEN, pEnumList);
  ItemsFetched := 0;

  while pEnumList.Next(1, pidChild, ItemsFetched) = NO_ERROR do
  begin

    psfFont.GetUIObjectOf(0, 1, pidChild, IID_IExtractIconW, nil,
      Pointer(ExtractIcon));

    Flags := 0;
    LH := 0;
    SH := 0;

    if Assigned(ExtractIcon) then
    begin
      IconIndex := 0;
      Icon := TIcon.Create;
      ExtractIcon.GetIconLocation(0, @IconFile, MAX_PATH, IconIndex,
        Flags);
      if (IconIndex < 0) or ((Flags and GIL_NOTFILENAME) = 0) then
        ExtractIconEx(@IconFile, IconIndex, LH, SH, 1)
      else
        ExtractIcon.Extract(@IconFile, IconIndex, LH, SH, MakeLong(32,
          16));

      //get font file icon's handle LS for large icon , SH for small icon
      //do something u want 

    end;

  end;

end;

Upvotes: 0

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108963

My guess is that you want the icon associated with the file type of a font file (TTF, for instance). Then you can just ask for this. For instance,

var
  sfi: SHFILEINFO;
begin
  SHGetFileInfo('C:\SomeFileThatNeedNotEvenExist.ttf',
    0, sfi, SizeOf(sfi), SHGFI_USEFILEATTRIBUTES or SHGFI_ICON);
  Image1.Picture.Icon.Handle := sfi.hIcon;

will get you the icon associated with TTF files.

Upvotes: 1

Related Questions