Jun 252014

Once in a while you want to set the caret position (aka cursor position) in a TMemo to a given line and character in that line. If you google for it you will find lots of hits that tell you to do the following:

With Memo1 do
    SelStart := Perform(EM_LINEINDEX, Line, 0);

or without the ugly with statement

Memo1.SelStart := Memo1.Perform(EM_LINEINDEX, Line, 0);

But that looks to be at least pre-Delphi 2007 because there already is a TMemo.CaretPos property that does the same:

Memo1.CaretPos := Point(0, Line);

This is a lot easier to understand than the above. Note that you can’t just assign only x or y like this:

Memo1.CaretPos.y := Line; // does not work!

This won’t work, because accessing CaretPos calls a getter method that returns a TPoint value. Changing this value does not change the CaretPos property, you must write the actual CaretPos property.

Unfortunately, while this works fine in general, Borland has introduced a bug in TCustomGrid.Paint that breaks this (both) code. If you have got a TCustomGrid descendant (TStringGrid and friends) on the form or a different form, you might find that the caret of the memo shows at the position where it would be on the grid. See QC 25702 for a description and workaround.
The workaround requires you to modify the VCL unit Grids.pas. To do that you should copy it from the Delphi installation to your project’s source code, add it to your project and only then modify it. Otherwise you might end up with a Delphi update overwriting it or even worse, failing to install.

Sorry, the comment form is closed at this time.

%d bloggers like this: