position of caret after marking a word/area

General TRichView support forum. Please post your questions here
Post Reply
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

position of caret after marking a word/area

Post by j&b »

After marking a word (sentence).
How can I find out whether the caret stands at the beginning or end of a selected word (sentence).
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

See GetSelectionBounds method.
Call RichViewEdit.TopLevelEditor.GetSelectionBounds(..., False), and check the returned values.
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

Post by j&b »

Hello Sergey,
thank you for your fast help.

memo.GetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs, true);
memoPos:=RVGetLinearCaretPos(memo);
laenge:= length(memo.getseltext);

ShowMessage(intToStr(StartItemNo)+' * '+intToStr(StartItemOffs)+' * '+intToStr(EndItemNo)+' * '+intToStr(EndItemOffs)+#13#10+
intToStr(memoPos)+' * '+intToStr(memoPos+laenge));


I have problems with memo.GetSelectionBounds(StartItemNo, ...) and RVGetLinearCaretPos(memo)
If I stand at the beginning of a marked text I want to set caret at the end of the marked text.

3 * 6 * 4 * 18 // GetSelectionBounds
95 * 112 // memoPos * memoPos+laenge


Background:

I mark a text. Then I change font.color to blue and I underline the marked text by clicking a button (or F11).

if I mark the text from left to right I stand at the end of the marked text.
If I press RETURN I change to the next line, BUT the new text has the attributes (blue and underlined) of the marked text.

This I can change:
//look some lines below //<<<<-------------------------------
cd.color:= 0; Memo.ApplyStyleConversion(rv_COLOR);
Memo.ApplyStyleConversion(rv_CLEARUNDERLINE);
if query1.state in [dsEdit, dsInsert] then query1.Post;


But if caret stands at the beginning of marked text I first have to set caret at the end of the marked text. Therfore I must know if I stand at the beginning or end of the marked text

...
memo.GetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs, true);
memoPos:=RVGetLinearCaretPos(memo); laenge:= length(memo.getseltext); memo.deselect;

//ShowMessage(intToStr(StartItemNo)+' * '+intToStr(StartItemOffs)+' * '+intToStr(EndItemNo)+' * '+intToStr(EndItemOffs)+#13#10+
// intToStr(memoPos)+' * '+intToStr(memoPos+laenge));

//if caret stands at the beginning then
RVSetLinearCaretPos(memo,memoPos+laenge); // <<<<------------------------

cd.color:= 0; Memo.ApplyStyleConversion(rv_COLOR);
Memo.ApplyStyleConversion(rv_CLEARUNDERLINE);
if query1.state in [dsEdit, dsInsert] then query1.Post;
Last edited by j&b on Sun Sep 28, 2008 10:08 am, edited 1 time in total.
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

If you call GetSelectionBounds with the last parameter = True, the selection will be returned in "normalized form", i.e. as if the caret is at the end of selection.

This code moves the caret to the end of selection:

Code: Select all

memo.TopLevelEditor.GetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs, true); 
if StartItemNo>=0 then // selection exists
  memo.TopLevelEditor.SetSelectionBounds(StartItemNo, StartItemOffs, EndItemNo, EndItemOffs); 
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

Post by j&b »

Thank you.

In the meantime I have found following solution

memoPos:=RVGetLinearCaretPos(memo);
laenge:= length(memo.getseltext);
if memo.OffsetInCurItem>laenge+1 then RVSetLinearCaretPos(memo,memoPos+laenge);
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

It's not a solution, because comparing offset of the caret position in item and text selection length gives nothing.
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

Post by j&b »

It works correct. 34x tested.

Why ?
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Selection may include several items. In this case OffsetInCurItem may be small and laenge may be large, regardless of the caret position.

If you want to use functions from RVLinear.pas, you can use RVGetSelection. If the caret is before the selection, SelLength is negative:

Code: Select all

var SelStart, SelLength: Integer;
begin
  RVGetSelection(RichViewEdit1, SelStart, SelLength);
  if SelLength<0 then
    RVSetSelection(RichViewEdit1, SelStart+SelLength, -SelLength);
end;
Note that GetSelectionBounds and SetSelectionBounds work faster than RVGetSelection and RVSetSelection.
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

Post by j&b »

Thanks.

Your help is wonderful :P
Post Reply