Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Line index in Richedit (https://www.delphipraxis.net/180082-line-index-richedit.html)

Gutelo 21. Apr 2014 20:46

Line index in Richedit
 
Hallo,

Wie bekommt man die Line-Indizes der ersten und letzten Zeile, die in einem Richedit angezeigt werden?

Was ich machen moechte:

Ich habe eine feste Position im Richedit (User hat vorher etwas markiert). Der User kann im Richedit scrollen. Nachdem ein Button gedrueckt wird soll das Richedit zurueck zur festen Position scrollen und zwar so, dass die Linie mit der Position mittig im Richedit liegt. Das scrollen erledige ich mit:

Delphi-Quellcode:
RichEdit1.Selstart := MyPos;
Das Problem ist, dass das scrollen unterschiedliche Ergebnisse liefert abhaengig davon ob der User vorher oberhalb oder unterhalb zur Postion gescrollt hat. In den beiden Faellen wird die Linie mit MyPos entweder als erste oder als letzte Linie in Richedit angezeigt. Dadurch kann ich nicht einfach weitere Linien mittels

Delphi-Quellcode:
SendMessage(RichEdit1.Handle, EM_LINESCROLL,0,-10);
scrollen da die Richtung nicht bekannt ist.

Wie bekomme ich information darueber welche Linien gerade im ClientRect angezeigt werden?

Gutelo

Popov 21. Apr 2014 21:35

AW: Line index in Richedit
 
Also wenn du was findest, kannst du dich melden. Ich hab zu dem Punkt auch was gesucht, konnte bisher aber nichts finden. Das Problem ist RichEdit. Bei Memo ist es einfacher.

Die einzige Idee die ich habe ist den ganzen Text Zeile für Zeile und Buchstabe für Buchstabe durchgehen und in jeder Zeile den Buchstaben finden der die größte Höhe benötigt. Dieser Wert bildet dann den Wert für diese Zeile. Aus diesen Werten kann man dann die Top-Zeile ermitteln.

Volker Z. 21. Apr 2014 22:37

AW: Line index in Richedit
 
Hallo,

Zitat:

Ich habe eine feste Position im Richedit (User hat vorher etwas markiert). Der User kann im Richedit scrollen. Nachdem ein Button gedrueckt wird soll das Richedit zurueck zur festen Position scrollen und zwar so, dass die Linie mit der Position mittig im Richedit liegt.
Naja, ganz genau mittig wirst Du das AFAIK nicht hinbekommen.

Vielleicht kommt folgendes dem nahe, was Du erreichen möchtest (nur mal vertikal).
Delphi-Quellcode:
const
  EM_GETSCROLLPOS = WM_USER + 221;
  EM_SETSCROLLPOS = WM_USER + 222;

procedure TForm4.Button1Click(Sender: TObject);
var
  p1, p2 : TPoint;
begin
  RichEdit1.SetFocus;
  SendMessage (Richedit1.Handle, EM_GETSCROLLPOS, 0, LParam (@p1));
  RichEdit1.SelStart := FSelStart;
  RichEdit1.SelLength := FSelLength;
  SendMessage (Richedit1.Handle, EM_GETSCROLLPOS, 0, LParam (@p2));
  if p1.Y - p2.Y < 0 then
    Inc (p2.Y, Richedit1.height div 2)
  else
    Dec (p2.Y, Richedit1.height div 2);

  SendMessage (Richedit1.Handle, EM_SETSCROLLPOS, 0, LParam (@p2))
end;

procedure TForm4.RichEdit1Exit(Sender: TObject);
begin
  FSelStart := RichEdit1.SelStart;
  FSelLength := RichEdit1.SelLength
end;
Gruß

Gutelo 21. Apr 2014 22:47

AW: Line index in Richedit
 
Also fuer den index der ersten sichtbaren Line hab ich folgendes gefunden:

Code:
RichEdit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
Den index der Selection bekommt man mit:

Code:
richedit1.caretpos.y;
Fuer die letzte sichtbare Line:

Code:
function RE_GetLastVisibleLine(RichEdit: TRichEdit): Integer;
const
  EM_EXLINEFROMCHAR = WM_USER + 54;
var
  r: TRect;
  i: Integer;
begin
  {
   The EM_GETRECT message retrieves the formatting rectangle
   of an edit control.
  }
  RichEdit.Perform(EM_GETRECT, 0, Longint(@r));
  r.Left := r.Left + 1;
  r.Top := r.Bottom - 2;
  {
    The EM_CHARFROMPOS message retrieves information about the character
    closest to a specified point in the client area of an edit control
  }
  i := RichEdit.Perform(EM_CHARFROMPOS, 0, Integer(@r.topleft));
  {
    The EM_EXLINEFROMCHAR message determines which
    line contains the specified character in a rich edit control
  }
  Result := RichEdit.Perform(EM_EXLINEFROMCHAR, 0, i);
end;
Quelle: http://delphi.cjcsoft.net//viewthread.php?tid=49413 und http://www.swissdelphicenter.ch/de/showcode.php?id=1213

Gutelo 21. Apr 2014 23:53

AW: Line index in Richedit
 
Meine Loesung Zum Zentrieren der Selection-Line im Richedit:

Delphi-Quellcode:
procedure TForm.Button1Click(Sender: TObject);
const
  EM_EXLINEFROMCHAR = WM_USER + 54;
var FirstLine, LastLine, SelLine : Integer;
    LinesToScroll : Integer;
    r: TRect;
    i: Integer;
begin
 // Get selection line
  SelLine := Richedit1.caretpos.y;
 // Get first visible line
  FirstLine := RichEdit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
 // Get last visible line
  RichEdit1.Perform(EM_GETRECT, 0, Longint(@r));
  r.Left := r.Left + 1;
  r.Top := r.Bottom - 2;
  i := RichEdit1.Perform(EM_CHARFROMPOS, 0, Integer(@r.topleft));
  LastLine := RichEdit1.Perform(EM_EXLINEFROMCHAR, 0, i);
 // Center selection in Richedit by scrolling
  LinesToScroll := -Round(0.5*(LastLine+FirstLine) - SelLine);
  RichEdit1.Perform(EM_LINESCROLL, 0, LinesToScroll);
end;

Popov 22. Apr 2014 00:55

AW: Line index in Richedit
 
Ach ja, der Code. Ich hab da etwas verwechselt.

Der Code funktioniert vermutlich so lange, solange du die Delphi-Standard-Eigenschaften nutzt. Problematisch wird es, wenn man die zusätzlichen Möglichkeiten von RichEdit nutzt. Er wird dann nicht falsch, er wird nur leicht ungenau, z. B. wenn man den Zeilenabstand manipuliert. Dann sieht man noch die vorherige Zeile, während die Funktion schon die neue Zeile als oberste Zeile angibt.

Gutelo 22. Apr 2014 02:44

AW: Line index in Richedit
 
was dachtest du?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz