
|
|
|
もくじ ・ 前のページ ・ 次のページ
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 は必要ありません。
もくじ ・ 前のページ ・ 次のページ
|
|