もくじ前のページ次のページ
4.TokenToFountainColor メソッド
TEditor は、文字列を描画する際、該当文字列をパーサーのインスタンスに渡してトークンを取得し、さらに、そのトークンをどういう「背景色・文字色・フォントスタイル」で描画すれば良いのかをパーサーに問い合わせます。これに応えるメソッドが TokenToFountainColor メソッドです。ここでは、コンストラクタで受け取った TFountain コンポーネントに保持されている描画情報フィールドの中で現在のトークンに対応するものを返しています。

TFountainParser は、コンストラクタで受け取った TFountain コンポーネントのインスタンスを FFountain: TFountain; フィールドデータに保持しておき、必要に応じて、その Brackets, ReserveWordList プロパティや描画情報フィールドを参照します。Brackets, ReserveWordList については TFountain クラスのプロパティなので、そのまま利用出来ますが、TFountain 拡張クラスに実装されるプロパティやメソッドへ手を伸ばすためには FFountain フィールドデータをキャストしてやる必要があります。TDelphiFountainParser では、

function TDelphiFountainParser.TokenToFountainColor: TFountainColor;
begin
  with TDelphiFountain(FFountain) do
    if IsReserveWord then
      Result := Reserve
    else
      case FToken of
        toSymbol:
          Result := FSymbol;
        toInteger, toFloat:
          Result := FInt;
        ............


という具合に FFountain を TDelphiFountain にキャストしています。この下位クラスへのキャストをダウンキャストと言います。これをやらないと、FSymbol, FInt といった TDelphiFountain に実装されたフィールドデータへアクセスすることが出来ません。
このダウンキャストは、TDelphiFountainParser のコンストラクタで受け取った Fountain が、TDelphiFountain のインスタンスであることが保証されているからこそ可能な技であることに注意して下さい。これは、ヘルプファイルの「TFountain の拡張」にもある通り、パーサークラスは、自身がどんな TFountain コンポーネントのために存在しているのかを知っていることを意味します。TDelphiFountainParser のコンストラクタは、受け取る Fountain が TDelphiFountain であることを信じて疑いませんので、

Parser := TDelphiFountainParser.Create(HTMLFountain1);

といったことはしないで下さい。開発時点では、コンストラクタが受け取る Fountain が自身の相手に相応しいかどうかを判別するメソッドの実装も考えたのですが、正しい使い方をする限り必要の無いメソッドを override しなければならないのはいかがなモノかということで実装していません。

実装する場合は、例えば

type
  TFountainEx = class(TFountain);
  
  TFountainParserEx = class(TFountianParser)
  protected
    function RightFountain(AFountain: TFountain): Boolean; virtual;
  public
    constructor Create(Fountain: TFountain); override;
  end;

constructor TFountainParserEx.Create(Fountain: TFountain);
begin
  inherited Create(Fountain);
  if not RightFountain(Fountain) then
    raise Exception.Create(Fountain.ClassName + ' is not my Fountain');
end;

function TFountainParserEx.RightFountain(AFountain: TFountain): Boolean;
begin
  Result := AFountain is TFountainEx;
end;

  といった感じになると思います。

  Parser := Editor1.ActiveFountain.ParserClass.Create(
              Editor1.ActiveFountain);
  
  というコーディングスタイルを守る限り RightFountain は必要ありません。



もくじ前のページ次のページ


[PR]看護師の好条件求人なら:看護師の転職完全サポート!安心お任せ♪