EM_UNDO does not work after programmatically writing to rich edit

535 Views Asked by At

Working in C++ Builder 10 Seattle on Win7-64.

I have a TRichEdit control into which I can write from a button click event:

MyRichEdit->SelText = t_string;

I want to be able to undo that change, so I have a menu item with shortcut Ctrl+Z that does this:

SendMessage(MyRichEdit->Handle, EM_UNDO, 0, 0);

The Undo works as expected if I have typed into the rich edit, but not to undo the programmatically assigned "paste".

I had similar code in an old application that was built with Borland C++ Builder v6, and it works there.

My question then is: Should the above code undo the write-to-SelText? Or is there something else I need to do?

1

There are 1 best solutions below

1
David Heffernan On

The implementation of the SelText setter looks like this:

procedure TCustomEdit.SetSelText(const Value: string);
begin
  SendTextMessage(Handle, EM_REPLACESEL, 0, Value);
end;

The documentation for EM_REPLACESEL says:

Parameters

wParam

Specifies whether the replacement operation can be undone. If this is TRUE, the operation can be undone. If this is FALSE , the operation cannot be undone.

lParam

A pointer to a null-terminated string containing the replacement text.

The VCL is sending 0 which is FALSE and so the operation cannot be undone. You will need to avoid using SelText and instead send the EM_REPLACESEL directly, passing TRUE as wParam.

I examined the source code for the Delphi 6 VCL and it too always passes 0 for wParam when sending this message, so I would have expected the old versions of the VCL to behave in the same way. All the same, you now know how to resolve the issue.

As an aside, you can replace sending of EM_UNDO with a call to MyRichEdit->Undo() which does exactly the same thing.