x
• Status: Solved
• Priority: Medium
• Security: Public
• Views: 426

# Get Line/Column from Memo Position and the reverse.

I've got a memo, some text in it, and I need to set the cursor to a specific line and a specific column. So how do I get the value I need for SelStart?
The reverse operation would also be interesting. What I basically need is:
function MemoPositionToLineColumn(M: TMemo; Position: Integer): TPoint;
function LineColumntToMemoPosition(M: TMemo; LineColumn: TPoint): Integer;

0
Shellman
• 2
1 Solution

Commented:
function MemoPositionToLineColumn(M: TMemo; Position: Integer): TPoint;
var
pp:TPoint;
i, Line, Col: Integer;
begin
i:=0; Line := 0; Col := 0;
while position >= Length(M.Lines[i])+2 do begin
inc(Line);
Dec(position, Length(M.Lines[i])+2);
Inc(i);
end;
col := position;
pp.X := Line; pp.Y := Col;
result := pp;
end;

function LineColumntToMemoPosition(M: TMemo; LineColumn: TPoint): Integer;
var
i, Line, Col: Integer;
begin
Line := LineColumn.X;
Col := LineColumn.Y;
i:=0; result := Col;
while i < Line do begin
Inc(result, Length(M.Lines[i])+2);
Inc(i);
end;
end;

0

Commented:

function MemoPositionToLineColumn(M: TMemo; Position: Integer): TPoint;
begin
Result := Point(-1,-1);
If Assgined(M) then
M.Perform(EM_POSFROMCHAR,integer(result),m.SelStart);
end;

function LineColumntToMemoPosition(M: TMemo; LineColumn: TPoint): Integer;
begin
result := -1;
If Assgined(M) then
result := m.Perform(EM_CHARFROMPOS,0,Integer(LineColumn ));
end;

just from head, not tested, maybe the conversions are not right

meikl ;-)
0

All-around developerCommented:
Here's some code I wrote to get the row, column in a Memo, use it to your delight:

function RichRow(m: TCustomMemo): Longint;
begin
Result := m.PerForm(EM_LINEFROMCHAR,m.SelStart,0);
end;

function RichCol(m: TCustomMemo; Row: Integer): Longint;
begin
Result := m.SelStart-m.Perform(EM_LINEINDEX,Row,0);
end;

procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
Memo: TMemo;
Row: Integer;
Col: Integer;
begin
Memo := TMemo(Sender);
Row := RichRow(Memo);
Col := RichCol(Memo, Row);
Caption := Format('%d : %d', [Row, Col]);
StatusBar1.Panels.Items[sbpPosition].Text := Format('%d : %d',
[Row, Col]);
end;

procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Memo: TMemo;
Row: Integer;
Col: Integer;
begin
Memo := TMemo(Sender);
Row := RichRow(Memo);
Col := RichCol(Memo, Row);
Caption := Format('%d : %d', [Row, Col]);
StatusBar1.Panels.Items[sbpPosition].Text := Format('%d : %d',
[Row, Col]);
end;
0

All-around developerCommented:
Oh, sbpPosition is a constant that tells me which Panel to place the text in a multi-panel statusbar.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.