Thank you for your responses.
I tried the following but it always returns 0.
procedure TForm1.Button1Click(Sender: TObject);
var
line: integer;
begin
line := Memo1.Perform(201, Memo1.SelStart, 0);
end;
So, I wrote the following function that tries to determine the first and last index of lines that are selected. However, it only works if the user highlights text moving forward not backward. One thing to note, it is implemented to return the index of the caret when no line is selected - something I also want but did not see a need to communicate in the OP. Any better ideas?
procedure TForm1.Button1Click(Sender: TObject);
var
start,
finish: integer;
begin
GetLinesIndex(Memo1, start, finish);
ShowMessage(IntToStr(start) + ' - ' + IntToStr(finish));
end;
procedure TForm1.GetLinesIndex(memo: TMemo; var firstIndex: integer; var lastIndex: integer);
var
tf: boolean;
index,
len: integer;
strAtLastIndex: string;
begin
firstIndex := 0;
lastIndex := memo.CaretPos.Y;
strAtLastIndex := memo.Lines[lastIndex];
if (memo.SelLength = 0) then begin
{nothing selected}
firstIndex := lastIndex;
end else if ((memo.SelLength = Length(strAtLastIndex)) and (memo.SelText = strAtLastIndex)) then begin
{whole line selected}
firstIndex := lastIndex;
end else if (memo.CaretPos.X - memo.SelLength < 0) then begin
{
multiple lines selected - presuming selection made where X is at end of the selected text not at the beginning.
thus, user will have highlighted text moving forward not backwards.
sigh, how else to do it?
}
tf := true;
len := memo.SelLength - memo.CaretPos.X;
index := lastIndex;
while (tf) do begin
index := index - 1;
if ((index <= 0) or (len < Length(memo.Lines[index]))) then begin
tf := false
end else
len := len - Length(memo.Lines[index]);
end;
firstIndex := index;
end else if (memo.SelLength < Length(strAtLastIndex)) then begin
{partial line selected}
firstIndex := lastIndex;
end else begin
{this means error}
firstIndex := -1;
lastIndex := -1;
end;
end;