Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.08.2024, 06:13   #1
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию StringGrid и ClipBoard

Задача: сделать в grid-е popupmenu с действиями cut, сopy и paste. При попытке написать все самому не получается скопировать часть текста из ячейки, все время копируется всё содержимое ячейки. Если использовать стандартные действия, то задача частично решена, но на Delphi 7 и Win10 такое меню не всегда соответствует тому, что должно быть. Например, на добавленном в ячейку combobox все действия "недоступны", хотя в буфере есть что вставить как минимум. И при отключении своего меню и использованию меню win10 это работает. Собственно вопрос, как ищет target следующий код (почему он работает с выделенным текстом в ячейке, как его написать без использования класса) и почему он неработает (недоступны пункты) в combobox-е? (ActionList удален для понимания происходящего)
Код:
uses
...StdActns;
procedure TForm1.EditCopyClick(Sender: TObject);
var
  A:TEditCopy;
begin
  A:=TEditCopy.Create(Self);
  A.Execute;   //копирует выделенный текст из ячейки
  A.Free;
end;
а sg.CopyToClipboard; или sg.CopySelectionToClipboard; копирует весь текст в ячейке независимо от выделения...
Можно ли что то с этим сделать?
Alex70 вне форума Ответить с цитированием
Старый 03.08.2024, 16:35   #2
DeepFlake
Пользователь
 
Регистрация: 16.05.2024
Сообщений: 92
По умолчанию

>а sg.CopyToClipboard; или sg.CopySelectionToClipboard; копирует весь текст в ячейке независимо от выделения... Можно ли что то с этим сделать?

Вроде бы нет. tStringGrid так и должен себя вести.
Начиная с версии Delphi 2006 в нём есть tGridPanel . Если его заполнить tEdit 'ами или tMemo или tRichEdit , то возможно что контексное меню с copy/paste в них уже готовое. Стандартный action teditcopy и т.д. тоже должны работать,
DeepFlake вне форума Ответить с цитированием
Старый 03.08.2024, 17:31   #3
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию

Переформулирую...
Стандартный класс из 7-ки работает.

Цитата:
function TEditAction.GetControl(Target: TObject): TCustomEdit;
begin
{ We could hard cast Target as a TCustomEdit since HandlesTarget "should" be
called before ExecuteTarget and UpdateTarget, however, we're being safe. }
Result := Target as TCustomEdit;
end;
{ TEditCopy }

procedure TEditCopy.ExecuteTarget(Target: TObject);
begin
GetControl(Target).CopyToClipboard;
end;
Да, здесь не StringGrig.CopyToClipboard, а Target as TCustomEdit. Так что в итоге выступает в роли Target, что копирование работает и почему это не работает во встроенном в StringGrig combobar-e? Как это поправить без ухода с 7-ки? Слишком много переделывать придется...
Alex70 вне форума Ответить с цитированием
Старый 03.08.2024, 18:57   #4
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию

Частично решил:
Код:
 (sg.CellEditor as TCustomEdit).CopyToClipboard;
Но с combobox не получается ни в какую... Invalid class typecast
Alex70 вне форума Ответить с цитированием
Старый 04.08.2024, 14:06   #5
DeepFlake
Пользователь
 
Регистрация: 16.05.2024
Сообщений: 92
По умолчанию

Как вставляете combobox в stringgrid?
Используете собственный редактор ячеек или по умолчанию?
Есть ли для stringgrid обработчики нажатий кнопок мыши и клавиатуры, и что они делают?
Используете ли рисование в stringgrid?
DeepFlake вне форума Ответить с цитированием
Старый 04.08.2024, 15:34   #6
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию

Здесь вообще неважно как вставляется ComboBar и что на нем нарисовано. Берем чистую форму, кидаем на неё стандартные: ComboBar (csDropDown), Edit, PopUpMenu и ActionList. Делаем три стандартных действия: Cut, Copy и Paste. При подключении своего меню к ComboBar все действия недоступны на D7 и 10 win, а если отключить, то будет контекстное меню Win и все работает. На Edit все отлично работает в обоих случаях.
Проблема, насколько я понял в классах родителей и, конкретно в том, что у ComboBar режим редактирования не приводится к TCusomEdit.
Частично обойти это можно достаточно легко, если вообще не заморачиваться с классами и стандартными действиями, а написать свои обработчики, типа:
Для Copy
Код:
ClipBoard.AsText:=sg.Combobox.SelText;
А вот как решить это красиво, пока не допер. С одной стороны, RAD - это быстро, с другой, слишком много остается за кадром для полного понимания работы. Не удивлюсь, если на старших версиях будет другой результат.
Alex70 вне форума Ответить с цитированием
Старый 05.08.2024, 15:32   #7
DeepFlake
Пользователь
 
Регистрация: 16.05.2024
Сообщений: 92
По умолчанию

>Берем чистую форму, кидаем на неё стандартны ...

Сделал как вы написали, да, так и работает, причём даже в Lazarus и Linux. Если бы TCustomEdit был типом-интерфейсом, то никаких проблем не возникло бы, потому что TEdit реализовывал бы интерфейс TCustomEdit и TComboBox бы его реализовывал бы его, и никаких проблем приведения TComboBox к TCustomEdit не было бы. Но VCL разработана ещё до появления в языке Delphi типов-интерфейсов.

Ещё можно было бы как-то выкрутится, если бы в Delphi можно было для класса определять свой оператор приведения. Но такого вроде нет

Тут придётся выкручиваться, можно:
1. Использовать в контексном меню свои action'ы , а не стандартные, а в них как вы написали ClipBoard.AsText:= ... и т.д.
2. Использовать модифицированные стандартные Edit action'ы, которые умеют работать с TComboBox'ом. То есть сделать класс производный от TEditCopy, в нём переопределить ExecuteTarget и UpdateTarget, а в них делать проверку target-объекта, если он TComboBox то ... ну вы поняли.
3. Использовать модифицированный TComboBox, который умеет прикидываться TEdit'ом. Сделать класс производный от TComboBox, в него добваить невидимый TEdit-объект, в обработчике OnContextPopup делать синхронизацию TEdit'а с данными в комбобоксе и вызывать контексное меню для внутреннего Tedit-объекта . Потом обратно синхронизировать данные из Tedit в combobox.

вобщем, не совсем удобно
DeepFlake вне форума Ответить с цитированием
Старый 05.08.2024, 17:01   #8
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию

Благодарю за участие и идеи, и особенно, за конец пункта 2
(Я еще только учусь и пока не все перевариваю)
Может что и получится
Alex70 вне форума Ответить с цитированием
Старый 06.08.2024, 13:07   #9
DeepFlake
Пользователь
 
Регистрация: 16.05.2024
Сообщений: 92
По умолчанию

LCL из Lazarus'а похожа на VCL из Delphi 7. Можно смотреть её исходный текст если что-то непонятно.
https://wiki.freepascal.org/Lazarus_Documentation#LCL

это справочник по LCL
https://lazarus-ccr.sourceforge.io/docs/lcl/
там смотрите StdCtrls и StdActns
DeepFlake вне форума Ответить с цитированием
Старый 10.08.2024, 09:19   #10
Alex70
 
Регистрация: 03.08.2024
Сообщений: 6
По умолчанию

Наконец получил все, что хотел:
как ни крути, в итоге все сводится к:
Код:
SendMessage(Handle, WM_PASTE, 0, 0); //WM_COPY, WM_CUT
Получение Handle применительно к PopUpMenu:
Код:
if PopUpMenu1.PopupComponent is
В итоге все работает отлично без "стандартных действий", заточенных под TCustomEdit и т.п.
Описанное позволяет полностью закрыть вопрос о копировании/вставке в grid-ы, более того, в итоге копировать можно все и так, как нужно/хочется, например даты/время. Иногда это нужно/удобно.
Alex70 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
clipboard krGorka Общие вопросы Delphi 2 19.05.2016 14:33
Clipboard АлександрDelphi Общие вопросы Delphi 10 30.03.2016 00:24
Помогите с Clipboard Темка C++ Builder 1 03.08.2015 11:29
Clipboard [Qj] Общие вопросы .NET 1 21.08.2009 18:50