2

I wanted to use procedure Delete(Memo.Text, index, count) (or similar Insert). But I get message 'Constant object can not be passed as var parameter'. I know I can select text and to use this procedures with Seltext. But this way is a bit uncomfortable. Is there anything easier?

Michael
  • 41,989
  • 11
  • 82
  • 128
Runner
  • 23
  • 1
  • 3

2 Answers2

5

Text is a property rather than a variable. And Delete requires a variable. So you need to use a temporary variable. For instance

var
  str: string;
.... 
str := Memo1.Text;
Delete(str, index, count);
Memo1.Text := str;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    For the case in the question (to have the text of the memo modified) the alternative mentioned in the question (using seltext) is better. The api handles the change rather than the framework retrieving the whole text, modifying, and then re-setting. – Sertac Akyuz Mar 19 '17 at 21:50
3

You are trying to call System.Delete(), which takes a reference to a string variable as input. But TMemo.Text is a property (that uses a getter method), it is not a variable. That is why you are getting the "can not be passed as var parameter" error.

You could use a temporary variable, eg:

var 
  s: string;

s := Memo.Text;
Delete(s, index, count);
Memo.Text := s;

But this is very inefficient in general, as it has to make a complete copy of the Memo's current content in memory, then modify/reallocate it, and then reassign it back to the Memo, completely wiping the current content and parsing the new content. That is a lot of work for small changes.

A faster and more efficient choice is to use the Memo's SelStart/SelLength and SelText properties instead, eg:

Memo.SelStart := index;
Memo.SelLength := count;
Memo.SelText := '';

You can do the same when inserting new text, just set SelLength to 0 instead, eg:

Memo.SelStart := index;
Memo.SelLength := 0;
Memo.SelText := 'text to insert';

Using these properties may be "uncomfortable", but it really is a good choice, from memory and performance perspectives. Internally, they simply send Win32 EM_(GET|SET|REPLACE)SEL messages directly to the Memo's window, letting the OS handle the actual text management.

If you really want the most efficient way, use the Win32 messages directly, eg:

//delete
Memo.Perform(EM_SETSEL, index, index+count);
Memo.Perform(EM_REPLACESEL, 0, LPARAM(PChar('')));

//insert
Memo.Perform(EM_SETSEL, index, index);
Memo.Perform(EM_REPLACESEL, 0, LPARAM(PChar('text to insert')));
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770