XE6使用FMX(FireMonkey)取得系統字型列表(For Win/Mac OS)

早上看到大陸網友留言發問,在Delphi的VCL架構中,只要Screen.Fonts就可以取得系統的字型列表,那在FMX(FireMonkey)架構裡沒有Screen.Fonts,該如何取得系統的字型列表呢?壽山做了一個簡單的程式做回應跟說明囉:)

首先我們新增一個FireMonkey Desktop Application專案
螢幕快照 2014-06-21 上午11.54.13

 

 

接著在畫面上放三個元件,Listbox、Label以及Button螢幕快照 2014-06-21 上午11.56.45

 

首先,在Uses的下面加上

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

接著我們要寫一個CollectFonts的函數,讓程式在不同平台可以抓到字型。

主要運用的技巧是

Mac OS裡的NSFontManager
Windows裡的EnumFontFamiliesEx

{$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;

最後在Button1Click事件加上

procedure TForm1.Button1Click(Sender: TObject);
var fList: TStringList;
    i: Integer;
begin
  fList := TStringList.Create;
  CollectFonts(fList);
  Label1.Text := '系統字型數量'+ IntToStr(fList.Count);
  for i := 0 to fList.Count -1 do
  begin
     ListBox1.Items.Add(FList[i]);
  end;
  fList.Free;
end;

在Windows及Mac OS執行的畫面如下
10374079_10152084884031541_8800976866348499936_n

10402863_10152084884291541_3407519286840592873_n

GitHub >> https://github.com/superlevin/XE6FMXGetFonts

作者: 林壽山

目前任職於軟體公司研究開發部門,擔任專業處長,專注於.NET C# 開發,並具備豐富的POS 收銀系統與金流整合開發經驗。我精通各類支付系統的設計與開發,包含第三方支付(如綠界、藍新、歐付寶、速買配、馬來西亞 ePay/HappyPay、台新 One 碼)、行動支付(悠遊卡、一卡通、支付寶、微信支付、街口支付)、以及信用卡支付(聯合信用卡)。 熟悉多種開發技術,擅長PHP 網頁開發(CodeIgniter、Laravel 框架)、Delphi 程式設計、資料庫設計、C# WinForm/WebForm 應用開發、ASP.NET MVC、API 串接設計,並具備LINE 串接開發的豐富經驗。 除了技術開發之外,我也熱衷於技術分享,曾擔任台中學校產業學院講師 5 年,培育新一代的軟體開發人才,致力於推動軟體技術的應用與創新。 我對技術充滿熱忱,始終保持學習與探索的心態,期望透過軟體開發為企業與社會創造更大的價值。