[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

displaying current cursor position on status bar

Posted on 2006-03-22
9
Medium Priority
?
2,050 Views
Last Modified: 2012-06-27
Hi,

I am creating editor based on TSynMemo component from SynEdit suite. This component is similar to TMemo. I would like to write current row/column on status bar. To do so I have to put code in many, many places (OnKeyUp, OnClicked etc.) and it still doesn't work as expected in some situations. In TRichEdit control there's OnSelectionChange event which is best for such activity. Unfortunately neither in TSynMemo nor in TMemo this event exists. So my question - what is the best way to catch row/column (or SelStart) while editing text in TMemo.

Albi
0
Comment
Question by:albireo77
9 Comments
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 16257564
You could subclass the window and trigger to the EM_SETSEL message which sets the caret (that is what you are talking about).
0
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16259671
nope, processing em_setsel does not work with TMemo (i.e., this message is not sent to TMemo when user "manually" sets cursor pos / selection)
0
 
LVL 34

Expert Comment

by:Slick812
ID: 16262232
hello albireo77, , I do not remember  an API message for and mutiline edit to happen foe a claret change position?
Anyway, here is some code that can read out the claret position for a TMemo


procedure TForm2.SetLineNum;
var
MesRe, ChPos, Line: Integer;
begin // this gets the position and does a Label1 caption for claret position
MesRe := Memo1.Perform(EM_GETSEL, 0, 0);
ChPos := HIWORD(MesRe);
Line := Memo1.Perform(EM_LINEFROMCHAR, ChPos, 0);
MesRe := Memo1.Perform(EM_LINEINDEX, Line, 0);
if MesRe < 0 then
  Label1.Caption := '0:0'
  else
  Label1.Caption := IntToStr(Line+1)+' : '+IntToStr(1+ChPos - MesRe);
end;

procedure TForm2.Memo1Change(Sender: TObject);
begin // TMemo OnChange event
SetLineNum;
end;

procedure TForm2.Memo1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin  // OnMouseUp event
SetLineNum;
end;

procedure TForm2.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin // OnKeyUp event
if Key in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME, VK_END] then
  SetLineNum;
end;

 = = = = = = = = = = = = = = = = = =

this seems to work for me, but there may be other way to change the memo, that is not coded for here.
ask questions if you need more information
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16262292
About Slick812's SetLineNum - there's a TMemo().CaretPos that could be used to get "current caret position" - it could be a shorter way than sending those messages...
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 16265806
EM_SETSEL must be sent. TMemo.CaretPos uses it in its implementation.
0
 
LVL 4

Accepted Solution

by:
HillGroover earned 500 total points
ID: 16268475
You could always try the OnStatusChange event, it's always worked fine for me

procedure TForm1.SynMemo1StatusChange(Sender: TObject; Changes: TSynStatusChanges);
var
   p: TPoint;
begin
   if Changes * [scAll, scCaretX, scCaretY] <> [] then
      begin
         p := (Sender as TSynMemo).CaretXY;
         StatusBar1.SimpleText := Format('%6d:%3d', [p.Y, p.X]);
      end;
end;
0
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16269706
robert_marquardt, it uses em_setsel when setting caret position, not getting..


property CaretPos: TPoint read GetCaretPos write SetCaretPos;

function TCustomMemo.GetCaretPos: TPoint;
begin
  Result.X := LongRec(SendMessage(Handle, EM_GETSEL, 0, 0)).Hi;
  Result.Y := SendMessage(Handle, EM_LINEFROMCHAR, Result.X, 0);
  Result.X := Result.X - SendMessage(Handle, EM_LINEINDEX, -1, 0);
end;

procedure TCustomMemo.SetCaretPos(const Value: TPoint);
var
  CharIdx: Integer;
begin
  CharIdx := SendMessage(Handle, EM_LINEINDEX, Value.y, 0) + Value.x;
  SendMessage(Handle, EM_SETSEL, CharIdx, CharIdx);
end;



What I wanted to say in my 1st post was that TMemo does not receive em_setsel each time when selection changes. However, it's possible to set selection with em_setsel, but it does not matter this time.
0
 
LVL 6

Expert Comment

by:Hardi
ID: 16278105
TMemoBar can be attached to a T(Custom)Memo component to provide additional info/functionality for a Memo component, including the current location (row and column) of the caret (textual cursor)

http://delphi.about.com/library/weekly/aa083005a.htm
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 16278547
The TMemo probably does not receive the EM_SETSEL because it is sent to the Windows control TMemo uses.
I meant to subclass that window to catch the EM_SETSEL sent to it. The caret is probably only set via that message. The control sends this message probably also to itself.
You have found a solution so i just want to clarify this.
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses
Course of the Month18 days, 11 hours left to enroll

834 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