Delphi XE で RTF 対応のツール ヒント ウィンドウを実装しようとしています。リッチ テキストをレンダリングするために、オフスクリーン TRichEdit を使用しています。私は2つのことをする必要があります:
- テキストのサイズを測定します。
- テキストをペイントする
両方のタスクを達成するために、次のメソッドを作成しました。
procedure TLookupHintWindow.CallFormatRange(R: TRect; var Range: TFormatRange;
MustPaint: Boolean);
var
TextRect: TRect;
begin
RichText.SetBounds(R.Left, R.Top, R.Right, R.Bottom);
TextRect := Rect(0, 0,
RichText.Width * Screen.Pixelsperinch,
RichText.Height * Screen.Pixelsperinch);
ZeroMemory(@Range, SizeOf(Range));
Range.hdc := Canvas.Handle;
Range.hdcTarget := Canvas.Handle;
Range.rc := TextRect;
Range.rcpage := TextRect;
Range.chrg.cpMin := 0;
Range.chrg.cpMax := -1;
SendMessage(RichText.Handle, EM_FORMATRANGE,
NativeInt(MustPaint), NativeInt(@Range));
SendMessage(RichText.Handle, EM_FORMATRANGE, 0, 0);
end;
Range パラメーターが渡されるので、このメソッドの外で計算されたディメンションを使用できます。MustPaint パラメータは、範囲を計算する (False) かペイントする (True) かを決定します。
範囲を計算するには、次のメソッドを呼び出します。
function TLookupHintWindow.CalcRichTextRect(R: TRect; const Rtf: string): TRect;
var
Range: TFormatRange;
begin
LoadRichText(Rtf);
CallFormatRange(R, Range, False);
Result := Range.rcpage;
Result.Right := Result.Right div Screen.PixelsPerInch;
Result.Bottom := Result.Bottom div Screen.PixelsPerInch;
// In my example yields this rect: (0, 0, 438, 212)
end;
ペイントするには:
procedure TLookupHintWindow.DrawRichText(const Text: string; R: TRect);
var
Range: TFormatRange;
begin
CallFormatRange(R, Range, True);
end;
問題は、幅 438 ピクセル、高さ 212 ピクセルの四角形を計算するときに、実際には非常に幅が広く (クリッピングされ)、高さ 52 ピクセルしかない四角形を描画することです。
ワードラップをオンにしていますが、それは必要ないというのが私の印象でした。
何か案は?