[bugreport]Richmemo и CutToClipboard, CopyToClipboard fail

Вопросы использования сторонних (не входящих в состав FPC и Lazarus) утилит и библиотек.

Модератор: Модераторы

Ответить
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

[bugreport]Richmemo и CutToClipboard, CopyToClipboard fail

Сообщение forlazarus »

Здравствуйте, на форме есть:

RichMemo:TRichmemo;
Memo: TMemo;
SynEdit:TSynEdit;

Ничего не происходит, если выделить текст и обработать нажатие пункта меню так:

Код: Выделить всё

RichMemo.CutToClipboard;
Однако, это работает, выделенный текст вырезается в буфер, если то же сделать для Memo или SynEdit:

Код: Выделить всё

Memo.CutToClipboard;
Также если на форму положить TActionList и добавить новые стандартные действия EditCut1, EditCopy1 и выбрать эти действия в пунктах меню, то команды Вырезать, Копировать будут работать только для Memo, SynEdit, но не будут работать для RichMemo.

В linux mint, lazarus 4.4.0, сборка проекта для gtk2 и qt6.
Последний раз редактировалось forlazarus 08.12.2025 13:27:53, всего редактировалось 1 раз.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

В порядке части "мозгового штурма" : почему бы не пойти "другим путем" и просто эмулировать нажатие "Ctrl+C" и "Ctrl+V" (и если нужно "Ctrl+A")? :idea: (есть модуль mouseandkeyinput который достаточно подключить и можно писать что-то такое )

Код: Выделить всё

procedure TForm1.MyCopy;
begin
  Edit1.SetFocus;
  Application.ProcessMessages;
  KeyInput.Press(VK_CtrlA);
  KeyInput.Press(VK_CtrlC);
end;
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

Ничего не происходит или полный буфер становится пустым? Стоит поискать функции в компоненте, которые выделяют область текста для копирования. Может ему надо выделить что копировать.
Вариант два - запуск без отладчика программы.
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Сообщение forlazarus »

Alex2013 писал(а):почему бы не пойти "другим путем" и просто эмулировать нажатие "Ctrl+C" и "Ctrl+V" (и если нужно "Ctrl+A")? :idea: (есть модуль mouseandkeyinput который достаточно подключить и можно писать что-то такое
Спасибо за идею!
1. Нашёл lazmouseandkeyinput.lpk, использовал, подключил модуль mouseandkeyinput в uses.
2. Код получился рабочий для всех текстовых перечисленных компонентов, в т.ч. для Richmemo. В обработчике щелчка вот (для вырезать):

Код: Выделить всё

KeyInput.Apply([ssCtrl]);
KeyInput.Press('X');
KeyInput.Unapply([ssCtrl]);  
Добавлено спустя 8 минут 20 секунд:
Sharfik писал(а):Ничего не происходит или полный буфер становится пустым?
Буфер содержал прошлые строки. Не те, что копировались в момент щелчка.
И вырезание в Richmemo не работало совсем. Выделение строки оставалось как есть нетронутым.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

есть такой модуль clipbrd для работы с буфером обмена. И не надо делать никаких эмуляций нажатий.
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Сообщение forlazarus »

Спешу сообщить, что можно закомментировать в unit RichMemo метод CutToClipboard:

Код: Выделить всё

//procedure CutToClipboard; override; 
И ниже

Код: Выделить всё

(*
procedure TCustomRichMemo.CutToClipboard;
begin
if HandleAllocated then
   TWSCustomRichMemoClass(WidgetSetClass).CutToClipboard(Self);
end; 
*)
Тогда в программе в команде Richmemo.CutToClipboard будет вызываться метод CutToClipboard из StdCtrls, а не из RichMemo.
Строка вырезается в буфер.

Кроме того, теперь работает стандартное действие EditCut1 из ActionList при щелчке в меню и для RichMemo.
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

forlazarus писал(а):Спешу сообщить, что можно закомментировать в unit RichMemo метод CutToClipboard:
Вносить изменения в исходники компонента очень плохая идея.
Во-первых после обновления эти изменения или затрутся или будет конфликт.
Во-вторых:

Код: Выделить всё

 
//Note: RichMemo cannot use LCL TCustomEdit copy/paste/cut operations
    //      because there's no support for (system native) RICHTEXT clipboard format
    //      that's why Clipboard operations are moved to widgetset level    
Т.е. операции с буфером перенесены на уровень набора виджетов, но проблема в том, что реализация есть только для Win32/64 и carbon.

Правильно будет сделать через наследника

Код: Выделить всё

type
  TRichMemoEx = class(TRichMemo)
  public
    procedureCopyToClipboard; override;
  end;
Или же вообще тупо использовать Clipbrd

Код: Выделить всё

uses
  Clipbrd;

procedure TForm1.miCopyClick(Sender: TObject);
begin
  if RichMemo.SelLength > 0 then
    Clipboard.AsText := RichMemo.SelText;
end;  
Добавлено спустя 9 минут 44 секунды:
Re: [bugreport]Richmemo и CutToClipboard, CopyToClipboard fail
Форматирование конечно работать не будет ни в одном случае.
Если надо с форматированием, то надо или самому писать реализацию для gtk2 (через gtk_clipboard_set_with_data).
Хотя в принципе если копирование/вставка нужны только внутри самого приложения, то можно сделать костыль - складывать не в буфер обмена, а во временный экземпляр RichMemo...
forlazarus
новенький
Сообщения: 15
Зарегистрирован: 28.10.2021 10:29:33

Сообщение forlazarus »

WAYFARER писал(а):Т.е. операции с буфером перенесены на уровень набора виджетов, но проблема в том, что реализация есть только для Win32/64 и carbon
Спасибо за разъяснение. Надеюсь, это реализуют и под linux.
Ответить