?
Solved

Caret position

Posted on 2011-02-24
30
Medium Priority
?
441 Views
Last Modified: 2012-06-22
I have some problems with positioning of caret to the beginning of the next line after the ending of text.

So i made this test app to resolve problem in another code where looks something is conflicting.

I have just two TRichedits and a TButton.
 On Buttonclick event am coping text from Richedi1 to Richedi2.
I need to have caret positioned at the beginning of the next line after the line where ending of text is.
procedure TForm1.Button1Click(Sender: TObject);
begin
   richedit2.text:=richedit1.text;
   richedit2.SelStart:=length(richedit2.Text);
   richedit2.SetFocus;
end;

end.

Open in new window

0
Comment
Question by:pr2501
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 14
  • 11
  • 2
  • +1
30 Comments
 
LVL 22

Expert Comment

by:pivar
ID: 34974192
Hi,

I think you need to add a newline, since the caret can't be positioned after the text.

/peter
0
 
LVL 22

Expert Comment

by:pivar
ID: 34974222
I think that would be

richedit2.text := richedit1.text + #13 + #10;
richedit2.SelStart:=length(richedit2.Text);
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34974247
try this
procedure TForm1.Button1Click(Sender: TObject);
var
  CaretPos: Integer;
begin
  richedit2.text:=richedit1.text;
  CaretPos := length(Trim(richedit2.Text)) - (Length(richedit2.lines[richedit2.Lines.Count -1]));
  richedit2.SelStart := CaretPos;
  richedit2.SetFocus;
end;

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34974322
Sorry I misunderstood your question
procedure TForm1.Button1Click(Sender: TObject);
var
  CaretPos: Integer;
begin
  richedit2.text:=richedit1.text;
  CaretPos := length(Trim(richedit2.Text));
  if richedit2.lines[richedit2.Lines.Count -1] <> '' then
  begin
    richedit2.Lines.Add('');
    Inc(CaretPos, 2); //+eoln
  end;
  richedit2.SelStart := CaretPos;
  richedit2.SetFocus;
end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 34977684
Ewangoya
In test app it works fine.
But in working app is not.
Would you help me to ressolwe it?
0
 

Author Comment

by:pr2501
ID: 34986110
In my working code (not the test version from above) by clicking on button i am automatically inserting line of text. But no way to move caret to bagging of next line.

I must move it by typing on "enter".
So what code can simulate like enter was pressed?
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34989066

Sorry took so long to reply. Had a very busy week.
This will work for all cases
procedure TForm1.Button1Click(Sender: TObject);
var
  CaretPos: Integer;
begin
  richedit2.text := Trim(richedit1.text);
  richedit2.Lines.Add('');
  CaretPos := length(richedit2.Text);
  richedit2.SelStart := CaretPos;
  richedit2.SetFocus;
end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 34991287
No, still it does not work.

I am adding lines of text by clicking on the button using next:
 AddColorLine(RichEdit1, DateTimeToStr(Now)+'  '+' i ',form2.SelectedSb.Font.Color );
 

Way after typing of character "d" (attached picture) caret moves from position (see arrow) to the end of the line next time i press on button?
   
procedure tform2.AddColorLine (RichEdit : TRichEdit; Str : String; Color : TColor);
var
  pos_start      : Integer;
  pos_end ,line ,CaretPos      : Integer;
  old_SelAttr    : TTextAttributes;
begin
  // take the old SelAttributes
  old_SelAttr := RichEdit.SelAttributes;
  // get the end pos
  pos_start := length(RichEdit.Text);
  // add the text
  RichEdit.Lines.Add(Str);
  // the the new end position
  pos_end := length(RichEdit.Text);
  // colorize the text
  RichEdit.SelStart := pos_start;
  RichEdit.SelLength := pos_end - pos_start;
  RichEdit.SelAttributes.Color := Color;
  // put back the old attributes
  RichEdit.SelAttributes := old_SelAttr;

RichEdit1.SelStart := length(RichEdit1.Text);
RichEdit1.SetFocus;

  end;

Open in new window

caretpozition.JPG
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34991737
here, add an empty line
procedure tform2.AddColorLine (RichEdit : TRichEdit; Str : String; Color : TColor);
var
  pos_start      : Integer;
  pos_end ,line ,CaretPos      : Integer;
  old_SelAttr    : TTextAttributes;
begin
  // take the old SelAttributes
  old_SelAttr := RichEdit.SelAttributes;
  // get the end pos
  pos_start := length(RichEdit.Text);
  // add the text
  RichEdit.Lines.Add(Str);
  // the the new end position
  pos_end := length(RichEdit.Text);
  // colorize the text
  RichEdit.SelStart := pos_start;
  RichEdit.SelLength := pos_end - pos_start;
  RichEdit.SelAttributes.Color := Color;
  // put back the old attributes
  RichEdit.SelAttributes := old_SelAttr;

  //Add an empty line then move to it
  RichEdit1.Add('');
  RichEdit1.SelStart := length(RichEdit.Text);
  RichEdit1.SetFocus;

  end;

Open in new window

0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34991740
Change to
procedure tform2.AddColorLine (RichEdit : TRichEdit; Str : String; Color : TColor);
var
  pos_start      : Integer;
  pos_end ,line ,CaretPos      : Integer;
  old_SelAttr    : TTextAttributes;
begin
  // take the old SelAttributes
  old_SelAttr := RichEdit.SelAttributes;
  // get the end pos
  pos_start := length(RichEdit.Text);
  // add the text
  RichEdit.Lines.Add(Str);
  // the the new end position
  pos_end := length(RichEdit.Text);
  // colorize the text
  RichEdit.SelStart := pos_start;
  RichEdit.SelLength := pos_end - pos_start;
  RichEdit.SelAttributes.Color := Color;
  // put back the old attributes
  RichEdit.SelAttributes := old_SelAttr;

  //Add an empty line then move to it
  RichEdit.Add('');
  RichEdit.SelStart := length(RichEdit.Text);
  RichEdit.SetFocus;

  end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 34992231
Now after i click to add new line caret moves for 2 lines down.
caretpozition.2JPG.JPG
0
 

Author Comment

by:pr2501
ID: 34992336
I have  two situations:

1. from picture in previous post:
just clicking on a button many times. itch time caret is positioned 2 lines after text.
What is wrong.

2.picture in this post:
itch time i click on a button i add character also,
and in this situation is alright.
caretpozition3.JPG
0
 
LVL 38

Accepted Solution

by:
Geert Gruwez earned 1200 total points
ID: 34995094
works with this:
procedure TForm1.CopyRT(re1, re2: TRichEdit);
var m: TStream;
begin
  m := TMemoryStream.Create;
  try
    re1.Lines.SaveToStream(m);
    m.Seek(0, soFromBeginning);
    re2.Lines.LoadFromStream(m);
  finally
    m.Free;
  end;
end;

procedure TForm1.MoveRTCaretEnd(re: TRichEdit);
begin
  re.SelLength := 0;
  re.SelStart := Length(re.Lines.Text);
  if re.CaretPos.X > 1 then
  begin
    re.Lines.Append('');
    re.SelLength := 0;
    re.SelStart := Length(re.Lines.Text);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyRT(RichEdit1, RichEdit2);
  MoveRTCaretEnd(RichEdit2);
end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 34999352
I have used code below and no help the problem still insists.
Am sorry. I do not know what to say.

This is the last thing what must i resolve to complete this phase of project.
Thank you.
richedit1.SelLength := 0;
   richedit1.SelStart := Length( richedit1.Lines.Text);
  if  richedit1.CaretPos.X > 1 then
  begin
    richedit1.Lines.Append('');
    richedit1.SelLength := 0;
    richedit1.SelStart := Length( richedit1.Lines.Text);
  end;

Open in new window

0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35013521
Trim the added string, lets try this way
procedure tform2.AddColorLine (RichEdit : TRichEdit; Str : String; Color : TColor);
var
  pos_start      : Integer;
  pos_end ,line ,CaretPos      : Integer;
  old_SelAttr    : TTextAttributes;
  Temp: string;
begin
  Temp := Trim(Str);
  // take the old SelAttributes
  old_SelAttr := RichEdit.SelAttributes;
  // get the end pos
  pos_start := length(RichEdit.Text);
  // add the text
  RichEdit.Lines.Add(Temp);
  // the the new end position
  pos_end := length(RichEdit.Text);
  // colorize the text
  RichEdit.SelStart := pos_start;
  RichEdit.SelLength := pos_end - pos_start;
  RichEdit.SelAttributes.Color := Color;
  // put back the old attributes
  RichEdit.SelAttributes := old_SelAttr;

  //Add an empty line then move to it
  RichEdit.Add('');
  RichEdit.SelStart := length(RichEdit.Text);
  RichEdit.SetFocus;

  end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 35019260
No it does not help.
I have took couple of days and maybe i will take some more to rest from this.

And then i will analyze the problem from the beginning.
It can't be so complicated. i just need to add line of text by an  event.
Maybe it is little more complicated because the text must be of special color, but...

Thank you
 
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35019279
No problem
0
 

Author Comment

by:pr2501
ID: 35021019
If i use  (' ') at the end t works. And with ('') it will not.
(attached code). But in this case i have empty space on the beginning of the line, and i would rather do not have it.

Now maybe some of Yours code which you post it already can make it work, but can you find it out for me, pleas?
.
AddColorLine(RichEdit1,DateTimeToStr(Now)+'  '+ 'i',form2.SelectedSb.Font.Color );    

    richedit1.Perform(EM_SCROLLCARET,0,0);
    richedit1.SelStart := Length( richedit1.Lines.Text);
    richedit1.SetFocus;
    richedit1.Lines.Add(' ');

Open in new window

// original version
procedure tform2.AddColorLine (RichEdit : TRichEdit; Str : String; Color : TColor);
var
  pos_start      : Integer;
  pos_end ,line ,CaretPos      : Integer;
  old_SelAttr    : TTextAttributes;
  Temp: string;
begin
  // take the old SelAttributes
  old_SelAttr := RichEdit1.SelAttributes;
  // get the end pos
  pos_start := length(RichEdit1.Text);
  // add the text
  RichEdit1.Lines.Add(str);
  // the the new end position
  pos_end := length(RichEdit1.Text);
  // colorize the text
  RichEdit1.SelStart := pos_start;
  RichEdit1.SelLength := pos_end - pos_start;
  RichEdit1.SelAttributes.Color := Color;
  // put back the old attributes
  RichEdit1.SelAttributes := old_SelAttr;
  end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 35021085
Maybe at the end (after all other code) i  should move caret for one position left (back)?
0
 

Author Comment

by:pr2501
ID: 35030469
   richedit1.Lines.Add('a');
    richedittext:=richedit1.Text;
    delete(richedittext, length(richedittext), 1);

Why i can not delete "a" with code above?
 
0
 

Author Comment

by:pr2501
ID: 35030503
And how many characters string variable can store.
To store a book what would i need?
0
 
LVL 32

Assisted Solution

by:Ephraim Wangoya
Ephraim Wangoya earned 800 total points
ID: 35032586

To delete
    richedit1.Lines.Add('a');
    //trim any extra characters from the text  
    richedittext := Trim(richedit1.Text);
    delete(richedittext, length(richedittext), 1);

You should not store a book in the database as a string of characters, that is not efficient for the database.
You need to use a binary format, you can store it as PDF or Word Document;

If you need to store a large number of books, you should consider storing the files on disk and having a field reference the location of the file. Large files in the database are not good for performance and also your database will grow very large very quickly.

Now back to that caret positioning, let me see if I can come up with any other idea
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35032704

To remove that last character, you actually need to truncate the EOLN and Carriage Return characters as well

var
  richedittext: string;
begin
 richedit1.Lines.Add('a');
 richedittext:= TruncateEOLN(Trim(richedit1.Text));
 delete(richedittext, length(richedittext), 1);
 richedit1.Text  := richedittext;
function TruncateEOLN(const S: string): string;
var
  Len: Integer;
begin
  Result := S;
  Len := Length(Result);

  while (Result[Len] in [#13, #10]) do
    Dec(Len);
  if Len <> Length(Result) then
    SetLength(Result, Len);
end;

Open in new window

0
 

Author Comment

by:pr2501
ID: 35033976
Not good, because this function moves caret to the start of RE and i get text font of all RE green.
0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 35034273
big mistake:
richedit.text := richedit.text

this will loose all formatting !!!!

i showed you how with streams
if you don't use the code with the stream copy, then your solution will never work.

richedit is not a good choice for big/large documents

0
 

Author Comment

by:pr2501
ID: 35035321
Thank you.
I will work on it after long wikend holiday.
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35036558

Was just showing you how to delete the last character, this has nothing to do with the issue of moving the caret to the end of the memo. That is yet to be solved.
I'm still looking into it
0
 

Author Comment

by:pr2501
ID: 35036840
thank you
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35237028

The Author is still waiting for my response, I'll work on this in the next few hours
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question