EM_UNDO не работает после программной записи в rich edit
Работа в C++ Builder 10 Сиэтл на Win7-64.
У меня есть элемент управления TRichEdit, в который я могу записать событие нажатия кнопки:
MyRichEdit->SelText = t_string;
Я хочу иметь возможность отменить это изменение, поэтому у меня есть пункт меню с сочетанием клавиш Ctrl+Z, который делает это:
SendMessage(MyRichEdit->Handle, EM_UNDO, 0, 0);
Отмена работает, как и ожидалось, если я набрал в расширенном редактировании, но не для отмены программно назначенной "вставки".
У меня был похожий код в старом приложении, которое было построено с Borland C++ Builder v6, и оно работает там.
Мой вопрос: должен ли приведенный выше код отменить запись в SelText? Или есть что-то еще, что мне нужно сделать?
1 ответ
Реализация SelText
Сеттер выглядит так:
procedure TCustomEdit.SetSelText(const Value: string);
begin
SendTextMessage(Handle, EM_REPLACESEL, 0, Value);
end;
Документация для EM_REPLACESEL
говорит:
параметры
WPARAM
Указывает, можно ли отменить операцию замены. Если это ИСТИНА, операция может быть отменена. Если это ЛОЖЬ, операция не может быть отменена.
LPARAM
Указатель на завершающуюся нулем строку, содержащую текст замены.
VCL отправляет 0
который FALSE
и поэтому операция не может быть отменена. Вам нужно будет избегать использования SelText
и вместо этого отправьте EM_REPLACESEL
прямо, проходя TRUE
как wParam
,
Я проверил исходный код для Delphi 6 VCL, и он тоже всегда проходит 0
за wParam
при отправке этого сообщения, поэтому я ожидал, что старые версии VCL будут вести себя так же. Все таки теперь вы знаете, как решить проблему.
Помимо этого, вы можете заменить отправку EM_UNDO
с призывом к MyRichEdit->Undo()
который делает то же самое.