【发布时间】:2011-10-13 09:31:09
【问题描述】:
我正在尝试在 Delphi XE 中实现支持 RTF 的工具提示窗口。为了呈现富文本,我使用了屏幕外的 TRichEdit。我需要做两件事:
- 测量文本的大小。
- 绘制文本
为了完成这两个任务,我写了这个方法:
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 像素高的矩形。
我打开了自动换行,虽然我的印象是不需要。
有什么想法吗?
【问题讨论】:
-
您不只是在您的工具栏控件上包含一个只读的 TRichTextEdit。听起来比你正在做的要容易得多。
-
如果我不让这个策略发挥作用,那就是我的计划。原因是工具提示通常具有渐变背景,该背景会被控件隐藏。这将使 RTF 工具提示在同一屏幕上脱颖而出。问题是,我使用相同的调用来进行计算,所以我希望这幅画能正常工作。
-
你不能让richedit透明,在背景中放一个稍微深一点的渐变吗?请参阅此处的一些透明度代码:stackoverflow.com/questions/7750224/…
标签: delphi delphi-xe off-screen trichedit