12/24 00:43 頃追記!
inline 指令が意味ないとのことです!
ソース内に書きました!
みなさん! FireMonkey 使ってますか!?
FireMonkey 使ってみると解るんですけど、痒いところに手が届かない事ありますよね!!
とはいえ、FireMonkey ではプラットフォームに依存するクラスは implementation の下に書いて、外出ししてないから置き換えられないよお!って事、良くありますよね。
ですが! FireMonkey には、サービスを置き換えるための仕組みがあります。
クラスそのものを置き換える事はできないのですが、その実体を提供している IFMXxxxx として提供されているサービスを置き換えられます!
今回は、その手法を紹介します。
基本的にはどのサービスも置き換えられるのですが、ここでは簡単のために IFMXSystemFontService を置き換えてみました(必要なメソッドが2つしかないので)。
デフォルトのフォント名を書き換えることで、下記の図のように設計時と実行時のフォントが変わります。
(上が設計時、下が実行時)
わ、解りづらいwww
詳しくは下記のソース内のコメントを参照してください!
unit FMX.SystemFontService;interfaceusesFMX.Platform;type// TInterfacedObject と目的のサービスのインターフェースを継承するTFMXSystemFontServiceHook = class(TInterfacedObject, IFMXSystemFontService)private var// 元々 FMX が登録していたサービスを保持する変数FOrgFMXSystemFontService: IFMXSystemFontService;protected// コンストラクタの中でサービスを置き換えるconstructor Create;public// 置き換えたいサービスが実装すべきメソッド{ IFMXSystemFontService }function GetDefaultFontFamilyName: String;function GetDefaultFontSize: Single; inline; // inline ついてはメソッド内にpublic// これを呼ぶとコンストラクタを呼べる!// 今回は Initialization で呼ぶclass procedure RegistService;end;implementationvar// このサービスのインスタンスを保持するSystemFontServiceHook: TFMXSystemFontServiceHook = nil;{ TFMXSystemFontServiceHook }constructor TFMXSystemFontServiceHook.Create;begininherited;// オリジナルの Interface を取り出して自分自身と置き換えてしまう!ifTPlatformServices.Current.SupportsPlatformService( // 取り出しIFMXSystemFontService,IInterface(FOrgFMXSystemFontService))then begin// オリジナルを削除TPlatformServices.Current.RemovePlatformService(IFMXSystemFontService);// 自分を登録しちゃうTPlatformServices.Current.AddPlatformService(IFMXSystemFontService, Self);end;end;function TFMXSystemFontServiceHook.GetDefaultFontFamilyName: String;begin// 元々のサービスが返す値を変えちゃう!Result := 'メイリオ';end;function TFMXSystemFontServiceHook.GetDefaultFontSize: Single;begin// 元々のサービスの値を返すこともできる// 置き換える予定の無いメソッドについては inline 指定をすると// 呼び出しオーバーヘッドが少なくなる// と思ったのですが、そんなことは無いそうです!!// 詳しくは、Lyna さんのこのツイートをご覧くださいResult := FOrgFMXSystemFontService.GetDefaultFontSize;end;// Initialization で↓このメソッドを呼んでコンストラクタを呼び出す// class constractor でも可能// これによって、このユニットをプロジェクトを追加するだけで自動的に置き換わる!class procedure TFMXSystemFontServiceHook.RegistService;beginif (SystemFontServiceHook = nil) thenSystemFontServiceHook := TFMXSystemFontServiceHook.Create;end;initializationTFMXSystemFontServiceHook.RegistService;end.
ということで、本日はクリスマスイブです!
なのに、こんなブログを書きました!書いたのは23日だけど!!
0 件のコメント:
コメントを投稿