Newsgroup: it.comp.lang.delphi
Titolo: Scrolling di un RichEdit

Come faccio, dopo aver aggiunto diverse righe da codice (tramite lines.add)
a fare si che il richedit si posizioni automaticamente sull'ultima riga,
avendo cioč la scroll bar giů del tutto?
Grazie
Iding

avendo cioè la scroll bar giù del tutto?
Sono un principiante, ma non vedendo altre risposte spero di esserti
utile ugualmente....
In rete avevo trovato domanda & risposta ad un quesito simile:
___________________________________________
"Ho messo una richedit dentro una scrollbox.
 Man mano inserisco del testo nella richedit e vorrei che la  scrollbar
verticale della scrollbox si posizionasse  in maniera tale da farmi
vedere sempre l'ultima riga inserita nellarichedit e non l'inizio del
testo inserito nella  richedit stessa.
Risposta:
Prova con:
    RichEdit.SelStart := SendMessage(RichEdit.Handle, EM_LINEINDEX,
Linea-1,0);
    RichEdit.SetFocus;      "
In pratica pone SelStart = char index della linea precedente e poi
attiva il focus. 
________________________________________
Altra variante:
Sposta il cursore alla fine del file
 Edit1.SelStart := Length(Edit1.Text) ;
Oppure all'inizio
Edit1.SelStart := 0;
ATTENZIONE: The edit or memo control must have input focus before you
change SelStart, or this will have no effect. 
_____________________________________________
Altra variante:
Set Caret Position in TMemo and TRichEdit boxes
Description
Use this to set the carot (cursor) position to a certain line. I assume
this code works for TRichEdit too.
procedure SetCaretPos(Memo: TMemo; LineNo: Integer);
begin
  if (LineNo<0) OR (LineNo>Memo.Lines.Count-1) then Exit;
  Memo.SelStart := Pos(Memo.Lines.Strings[LineNo], Memo.Text)-1;
  Memo.SelLength := 0;
  Memo.SetFocus;
end;
___________________________________________
In realtà anche seguendo alla lettera i consigli, talvolta non ottengo i
risulti (almeno con D3 in W2000, ora devo ancora provare D6) voluti per
problemi di focus (e rimedio in modi poco ortodossi....): ti auguro
maggior fortuna....
Se vuoi fare ricerche su internet, ricorda che quello che per noi è il
cursore (il punto in cui viene inserito il testo), viene in realtà
chiamato "caret" ("cursor" invece si riferisce al puntatore del mouse).
Se te le cavi con l'inglese ti consiglio di guardare anche la
descrizione delle API presenti nell'help della Borland (ti riporto un
estratto, molto alla rinfusa, di alcuni appunti tratti dalla rete o
dall'help; sicuramente ci sono errori ed imprecisioni, ma magari puoi
trarne qualche spunto se sei "bloccato"). 
Simone
________________________________________________________________
Ecco alcune API interessanti (per i dettagli vedi il file
Delphi3\HELP\WIN32.HLP):
Per quanto riguarda le funzioni sui  testi, esistono un:
- Zero-based character index =  A character index is the number of
characters from the beginning of the edit control. (in pratica è la
posizione considerando il testo come un unico array di char)
- Zero-based line index (n. di linee dall'inizio)
EM_LINEFROMCHAR 
 wParam = (WPARAM) ich;  // character index 
 lParam = 0;             // not used; must be zero 
An application sends an EM_LINEFROMCHAR message to retrieve the index of
the line that contains the specified character index in a multiline edit
control. A character index is the number of characters from the
beginning of the edit control. 
Riporta il n. di linea (partendo da 0) che corrisponde alla posizione
nel character index (cioè cui appartiene il char nell'array unico).
La funzione EM_LINEFROMCHAR (EM = Editing Memo [?]), riporta il n. di
linea dove si trova l' n. carattere: cioè  dandogli in input la
posizione assoluta del carattere (in questo caso del cursore, usando la
proprietà SelStart), riporta il n. di linea.
NumeroLinea:=SendMessage(Memo1.Handle,EM_LINEFROMCHAR,memo1.Selstart,0);
Viene riportato come Longint
Per ricavare anche la posizione orizzontale, si usa in più questa riga,
contenente la API EM_LINEINDEX la quale riporta il "character index"
(cioè la posizione, espressa in n. di char, considerando il testo come
un'unica stringa) della linea passata come parametro.
Facendo la differenza tra SelStart e quanto riportato da questa funzione
si ricava anche la colonna.
 
NumeroColonna := (RichEdit1.SelStart - SendMessage(RichEdit1.Handle,
EM_LINEINDEX, NumeroLinea, 0));
Sembra che per il RichEdit cambi il nome:
For TRichEdit you must send a EM_EXLINEFROMCHAR and EM_LINEINDEX
messages.
For TMemo you must send a EM_LINEFROMCHAR and EM_LINEINDEX messages.
 for TRichEdit
LineNumber  := SendMessage(RichEdit1.Handle, EM_EXLINEFROMCHAR, 0,
RichEdit1.SelStart);
ColNumber := (RichEdit1.SelStart - SendMessage(RichEdit1.Handle,
EM_LINEINDEX, LineNumber, 0));
PS: not forget that starting values is 0.
position of caret in memo in row/col format: 
  Row := Memo1.PerForm(EM_LINEFROMCHAR,Memo1.SelStart,0); 
  Col := Memo1.SelStart-Memo1.Perform(EM_LINEINDEX,Row,0);
position of caret in richedit control in row/col format: 
  Row := richedit1.PerForm(EM_EXLINEFROMCHAR,0,richedit1.SelStart); 
  Col := richedit1.SelStart-richedit1.Perform(EM_LINEINDEX,Row,0);
Se comunque sei nei casini e non ti viene mostrato il cursore
(ononstante i focus/update....), usa queste 4 righe :-(
   RichEdit1.perform( WM_KEYDOWN, VK_RIGHT, 1);  {Per far vedere il
cursore}
   RichEdit1.perform( WM_KEYUP, VK_RIGHT, 1);
   RichEdit1.perform(WM_KEYDOWN, VK_LEFT, 1);
   RichEdit1.perform(WM_KEYUP, VK_LEFT, 1);
__________________
EM_CHARFROMPOS 
 wParam = 0; 
 lParam = MAKELPARAM(x, y) 
An application sends an EM_CHARFROMPOS message to retrieve the
zero-based character index and zero-based line index of the character
nearest the specified point in an edit control.
Da X,Y --> posizione nell'array Text
EM_POSFROMCHAR 
wParam = (WPARAM)wCharIndex;       // zero-based index of character 
lParam = 0;                 // not used, must be zero 
An application sends the EM_POSFROMCHAR message to retrieve the
coordinates of the specified character in an edit control.
wCharIndex
Value of wParam. Specifies the zero-based index of the character.
Viceversa del precedente:  dalla posizione nel Text riporta X,Y
EM_GETFIRSTVISIBLELINE 
 wParam = 0; // not used; must be zero 
 lParam = 0; // not used; must be zero 
 An application sends an EM_GETFIRSTVISIBLELINE message to determine the
uppermost visible line in an edit control. 
This message has no parameters. 
The return value is the zero-based index of the uppermost visible line
in a multiline edit control. For single-line edit controls, the return
value is the zero-based index of the first visible character. 
SPERIMENTATO: Riporta il n. della prima linea visibile (0= prima linea))
EM_LINEINDEX 
 wParam = (WPARAM) line; // line number 
 lParam = 0;             // not used; must be zero 
An application sends an EM_LINEINDEX message to retrieve the character
index of a line in a multiline edit control. The character index is the
number of characters from the beginning of the edit control to the
specified line. 
The return value is the character index of the line specified in the
line parameter, or it is -1 if the specified line number is greater than
the number of lines in the edit control. 
Specifichi una linea e la API riporta il char-index del primo char di
questa linea (dove si trova nell'array unico il primo char della linea
che ti interessa)
EM_LINELENGTH 
wParam = (WPARAM) ich;  // character index 
lParam = 0;             // not used; must be zero 
 An application sends an EM_LINELENGTH message to retrieve the length of
a line, in characters, in an edit control. 
ich
Value of wParam. Specifies the character index of a character in the
line whose length is to be retrieved when EM_LINELENGTH is sent to a
multiline edit control. If this parameter is -1, the message returns the
number of unselected characters on lines containing selected characters.
For example, if the selection extended from the fourth character of one
line through the eighth character from the end of the next line, the
return value would be 10 (three characters on the first line and seven
on the next). 
The return value is the length, in characters, of the line specified by
the ich parameter when an EM_LINELENGTH message is sent to a multiline
edit control. The return value is the length, in characters, of the text
in the edit control when an EM_LINELENGTH message is sent to a
single-line edit control. 
Gli specifichi il char-index di un carattere qualsiasi di una data linea
e questa api riporta la lunghezza della linea (o quanti char non sono
selezionati) 
EM_LINESCROLL 
wParam = (WPARAM) cxScroll; // characters to scroll horizontally 
lParam = (LPARAM) cyScroll; // lines to scroll vertically 
 An application sends an EM_LINESCROLL message to scroll the text
vertically or horizontally in a multiline edit control. 
cxScroll
Value of wParam. Specifies the number of characters to scroll
horizontally. 
cyScroll
Value of lParam. Specifies the number of lines to scroll vertically. 
If the message is sent to a multiline edit control, the return value is
TRUE; if the message is sent to a single-line edit control, the return
value is FALSE. 
The edit control does not scroll vertically past the last line of text
in the edit control. If the current line plus the number of lines
specified by the cyScroll parameter exceeds the total number of lines in
the edit control, the value is adjusted so that the last line of the
edit control is scrolled to the top of the edit-control window. 
The EM_LINESCROLL message can be used to scroll horizontally past the
last character of any line. 
Effettua lo scrolling di tot linee in verticale e tot char in
orizzontale (senza muovere il cursore suppongo)
An application should use the EM_LINESCROLL message to scroll to a
specific line or character position. 
EM_SCROLLCARET 
 wParam = 0 ;    // not used now; reserved for future use; must be zero 
 lParam = 0 ;    // not used now; reserved for future use;  must be zero
An application sends an EM_SCROLLCARET message to scroll the caret into
view in an edit control. 
In previous versions of Windows, scrolling the caret into view was done
by specifying wParam = FALSE in the EM_SETSEL message. A Win32-based
application should use the EM_SCROLLCARET message to scroll the caret
into view. 
DALLE PROVE FATTE fa scrollare la finestra in modo che la linea col
cursore sia quella più in alto. NO: fa scrollare SOLO SE il cursore
attualmente non è visibile; per ottenre quanto sopra, devi prima dare
uno scroll di una pagina, costringendolo a sua volta  a scrollare e già
che c'è lo mette come prima linea
An application should use the EM_SCROLLCARET message to scroll the caret
into view. 
In realtà mi funziona solo se preceduto da   
richedit1.Perform( WM_VSCROLL, SB_PAGEDOWN, 0);
Forse i miei casini derivano anche dal fatto di avere Windows 2000
(which uses the wrapper richedit 1.0 and actual richedit 3.0: doesn't
observe it without focus being on the control. 
Va bene ad esempio quando carichi un file in un memo e la vista del memo
va all'ultima linea: per riportarla all'inizio (dove è rimasto il
cursore) chiama questa routine
EM_SCROLL 
wParam = (WPARAM) (INT) nScroll;    // scroll action 
lParam = 0;                         // not used; must be zero 
An application sends an EM_SCROLL message to scroll the text vertically
in a multiline edit control. This message is equivalent to sending a
WM_VSCROLL message to the edit control. 
nScroll
Value of wParam. Specifies the action the scroll bar is to take. This
parameter may be one of the following values: 
Value	Meaning
SB_LINEDOWN	Scrolls down one line.
SB_LINEUP	Scrolls up one line.
SB_PAGEDOWN	Scrolls down one page.
SB_PAGEUP	Scrolls up one page.
If the message is successful, the high-order word of the return value is
TRUE, and the low-order word is the number of lines that the command
scrolls. The number returned may not be the same as the actual number of
lines scrolled if the scrolling moves to the beginning or the end of the
text. If the nScroll parameter specifies an invalid value, the return
value is FALSE. 
Remarks
An application should use the EM_LINESCROLL message to scroll to a
specific line or character position. 
An application should use the EM_SCROLLCARET message to scroll the caret
into view. 
(forse le 2 righe sopra vogliono dire che prima scrolli la finestra e
poi fai comparire il cursore)
Equivale a mandare un messaggio di scroll di 1 linea oppure di 1 pagina
(va specificato).
_______________________________________________________
 All resistance is futile ! Prepare to be assimilated !