Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
Delphi 10.2 Tokyo Professional
|
Re: Bounding rectangle eines fromatierten RTF-Textes ermitte
2. Sep 2005, 10:24
So scheint's zu funktionieren:
Delphi-Quellcode:
function GetRichEditTextExtent(hRichEdit: HWND; nWidth: integer): TPoint;
var
dc: HDC;
fr: TFormatRange;
res: TPoint;
rv: integer;
begin
dc := GetDC(hRichEdit);
try
res.x := GetDeviceCaps( dc, LOGPIXELSX);
res.y := GetDeviceCaps( dc, LOGPIXELSY);
fr.hdc := dc;
fr.hdcTarget := dc;
fr.rc := Rect(0, 0, MulDiv(nWidth, 1440, res.x), $1000000);
fr.rcPage := fr.rc;
fr.chrg.cpMin := 0;
fr.chrg.cpMax := SendMessage(hRichEdit, WM_GETTEXTLENGTH, 0, 0);
rv := SendMessage(hRichEdit, EM_FORMATRANGE, 0, LPARAM(@fr));
SendMessage(hRichEdit, EM_FORMATRANGE, 0, 0);
Assert(rv >= fr.chrg.cpMax);
Result.x := MulDiv(fr.rc.Right, res.x, 1440);
Result.y := MulDiv(fr.rc.Bottom, res.y, 1440);
finally
ReleaseDC(hRichEdit, dc);
end;
end;
//EDIT: Berechnet aber offensichtlich nur die Höhe ...
[Nachtrag]
So berechnet er auch die Breite, aber perfekt ist's immer noch nicht wegen der Zeilenumbrüche. Diese Funktion ermittelt die "minimale Breite" die nötig ist, um die berechnet Höhe zu halten. Das kann anders aussehen als bei dir auf dem Bildschirm.
Delphi-Quellcode:
function GetRichEditTextExtent(hRichEdit: HWND; nWidth: integer): TPoint;
var
dc: HDC;
fr: TFormatRange;
res: TPoint;
txl: integer;
rv: integer;
wmin, wmid, wmax: integer;
function CalcHeight(w: integer): integer;
begin
fr.hdc := dc;
fr.hdcTarget := dc;
fr.rc := Rect(0, 0, MulDiv(w, 1440, res.x), $1000000);
fr.rcPage := fr.rc;
fr.chrg.cpMin := 0;
fr.chrg.cpMax := txl;
rv := SendMessage(hRichEdit, EM_FORMATRANGE, 0, LPARAM(@fr));
Assert(rv >= fr.chrg.cpMax);
Result := MulDiv(fr.rc.Bottom, res.y, 1440);
end;
begin
dc := GetDC(0);
try
res.x := GetDeviceCaps( dc, LOGPIXELSX);
res.y := GetDeviceCaps( dc, LOGPIXELSY);
txl := SendMessage(hRichEdit, WM_GETTEXTLENGTH, 0, 0);
Result.X := nWidth;
Result.Y := CalcHeight(Result.X);
wmin := 1;
wmax := nWidth;
while wmin <= wmax do
begin
wmid := (wmin + wmax) div 2;
if CalcHeight(wmid) <= Result.Y then
begin
Result.X := wmid;
wmax := wmid - 1;
end
else
wmin := wmid + 1;
end;
finally
SendMessage(hRichEdit, EM_FORMATRANGE, 0, 0);
ReleaseDC(0, dc);
end;
end;
Eine exakte Lösung wäre z.B., mit bekannter Breite und Höhe eine Bitmap zu erzeugen und das RichEdit dort hinein zeichnen zu lassen. Danach müsste man dann den rechten Rand dieser Bitmap überprüfen (ziemlich aufwändig).
|