RichEdit: Breite und Höhe des Inhalts bestimmen

Die Funktion GetRichEditTextExtent ermittelt die (Breite und) Höhe des Inhalts eines RichEdit-Steuerelements.

  • Der Parameter hRichEdit: ist das Handle des RichEdit-Steuerelements, also z.B RichEdit1.Handle.

  • Der Parameter nWidth gibt die Umbruchbreite an, für die die Höhe berechnet werden soll. Ist dieser Parameter 0, dann wird die Darstellungsbreite des RichEdit genommen.

  • Ist fExactWidth gesetzt, dann wird ebenfalls die zu dieser Höhe minimale Breite berechnet. Ansonsten ist Result.x die für die Berechnung benutzte Breite.

  • Der Parameter fSelection steuert, ob die Berechnung für den gesamten Text durchgeführt wird oder nur für die aktuelle Auswahl.

uses
  RichEdit;

function GetRichEditTextExtent(hRichEdit: HWND; nWidth: Integer;
  fExactWidth: Boolean = false; fSelection: Boolean = false): TPoint;
var
  dc: HDC;
  fr: TFormatRange;
  res: TPoint;
  wmin, wmid, wmax: Integer;

  // Berechnet die Umbruchbreite des RichEdit-Controls
  function ClientWidth: Integer;
  var
    rc: TRect;
  begin
    GetClientRect(hRichEdit, rc);
    SendMessage(hRichEdit, EM_GETRECT, 0, LPARAM(@rc));
    Result := rc.Right - rc.Left;
  end;

  // Berechnet für die Breite "w" die formatierte Höhe
  function CalcHeight(w: Integer): Integer;
  begin
    fr.rc := Rect(0, 0, MulDiv(w, 1440, res.x), $1000000);
    fr.rcPage := fr.rc;
    SendMessage(hRichEdit, EM_FORMATRANGE, 0, LPARAM(@fr));
    Result := MulDiv(fr.rc.Bottom, res.y, 1440);
  end;

begin
  dc := GetDC(0);
  try
    // Bildschirmauflösung für Twips <-> Pixel
    res.x := GetDeviceCaps(dc, LOGPIXELSX);
    res.y := GetDeviceCaps(dc, LOGPIXELSY);

    // Die FORMATRANGE-Struktur initialisieren
    fr.hdc := dc;
    fr.hdcTarget := dc;

    if fSelection then
      SendMessage(hRichEdit, EM_EXGETSEL, 0, LPARAM(@fr.chrg))
    else
    begin
      fr.chrg.cpMin := 0;
      fr.chrg.cpMax := -1;
    end;

    // Maximale Formatierungsbreite
    if nWidth <= 0 then
      Result.X := ClientWidth
    else
      Result.X := nWidth;

    // Für die maximale Breite die Höhe bestimmen
    Result.Y := CalcHeight(Result.X);

    if fExactWidth then
    begin
      // Dies ist nicht exakt. Wir berechnen hier nur die minimale
      // Breite, bei der der formatierte Text nicht höher als die
      // oben berechnet Basishöhe ist.
      wmin := 1;
      wmax := Result.X;

      // Binäre Suche
      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;
    end;
  finally
    // Ressourcen wieder freigeben
    SendMessage(hRichEdit, EM_FORMATRANGE, 0, 0);
    ReleaseDC(0, dc);
  end;
end;
Flocke's Garage
Valid HTML 4.01 Transitional Valid CSS!
(C) 2005-2018 Volker Siebert.
Creative Commons-LizenzvertragDer gesamte Inhalt dieser Webseite steht unter einer Creative Commons-Lizenz (sofern nicht anders angegeben).