如何获得可用的字体列表 - Delphi XE3 + Firemonkey 2?

时间:2012-11-12 15:34:26

标签: delphi firemonkey delphi-xe3 firemonkey-fm2

为了创建字体选择器,我需要获取Firemonkey可用的字体列表。 由于FireMonkey中不存在Screen.Fonts我以为我需要使用FMX.Platform? 例如:

if TPlatformServices.Current.SupportsPlatformService(IFMXSystemFontService, IInterface(FontSvc)) then
  begin
    edit1.Text:= FontSvc.GetDefaultFontFamilyName;
  end
  else
    edit1.Text:= DefaultFontFamily;

但是,唯一可用的功能是返回默认的字体名称。

目前我并不担心跨平台支持,但如果我要转移到Firemonkey,我宁可不依赖Windows调用。

3 个答案:

答案 0 :(得分:7)

跨平台解决方案应该在条件定义中一起使用MacApi.AppKit和Windows.Winapi。

首先将这些代码添加到您的uses子句中:

{$IFDEF MACOS}
MacApi.Appkit,Macapi.CoreFoundation, Macapi.Foundation,
{$ENDIF}
{$IFDEF MSWINDOWS}
Winapi.Messages, Winapi.Windows,
{$ENDIF}

然后将此代码添加到您的实现中:

{$IFDEF MSWINDOWS}
function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
var
  S: TStrings;
  Temp: string;
begin
  S := TStrings(Data);
  Temp := LogFont.lfFaceName;
  if (S.Count = 0) or (AnsiCompareText(S[S.Count-1], Temp) <> 0) then
    S.Add(Temp);
  Result := 1;
end;
{$ENDIF}

procedure CollectFonts(FontList: TStringList);
var
{$IFDEF MACOS}
  fManager: NsFontManager;
  list:NSArray;
  lItem:NSString;
{$ENDIF}
{$IFDEF MSWINDOWS}
  DC: HDC;
  LFont: TLogFont;
{$ENDIF}
  i: Integer;
begin

  {$IFDEF MACOS}
    fManager := TNsFontManager.Wrap(TNsFontManager.OCClass.sharedFontManager);
    list := fManager.availableFontFamilies;
    if (List <> nil) and (List.count > 0) then
    begin
      for i := 0 to List.Count-1 do
      begin
        lItem := TNSString.Wrap(List.objectAtIndex(i));
        FontList.Add(String(lItem.UTF8String))
      end;
    end;
  {$ENDIF}
  {$IFDEF MSWINDOWS}
    DC := GetDC(0);
    FillChar(LFont, sizeof(LFont), 0);
    LFont.lfCharset := DEFAULT_CHARSET;
    EnumFontFamiliesEx(DC, LFont, @EnumFontsProc, Winapi.Windows.LPARAM(FontList), 0);
    ReleaseDC(0, DC);
  {$ENDIF}
end;

现在您可以使用CollectFonts过程。不要忘记将非零TStringlist传递给该过程。典型用法可能是这样的。

procedure TForm1.FormCreate(Sender: TObject);
var fList: TStringList;
    i: Integer;
begin
  fList := TStringList.Create;
  CollectFonts(fList);
  for i := 0 to fList.Count -1 do
  begin
     ListBox1.Items.Add(FList[i]);
  end;
  fList.Free;
end;

答案 1 :(得分:4)

我使用了以下解决方案:

  Printer.ActivePrinter;
  memo1.lines.AddStrings(Printer.Fonts);

在使用中声明FMX.Printer。

答案 2 :(得分:0)

unit Unit1;

interface

uses
  Windows, SysUtils, Classes, Forms, Controls, StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}                      

procedure TForm1.FormShow(Sender: TObject);
begin
  ComboBox1.Items.Assign(Screen.Fonts);
  ComboBox1.Text := 'Fonts...';
end;

end.

unit Unit1; interface uses Windows, SysUtils, Classes, Forms, Controls, StdCtrls; type TForm1 = class(TForm) ComboBox1: TComboBox; procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormShow(Sender: TObject); begin ComboBox1.Items.Assign(Screen.Fonts); ComboBox1.Text := 'Fonts...'; end; end.