Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663

Реализация через PopupMenu функций copy and paste в DrawGrid

14.03.2016, 13:06. Показов 3230. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго дня! Встала задача реализовать данный сабж в пределах одного DrawGrid. При выделение одной, а еще лучше диапазона ячеек. В голову приходит некий еще один, временный DrawGrid (промежуточный хранитель). Как это правильно реализовать вообще? Может есть пример где - не найти. Спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.03.2016, 13:06
Ответы с готовыми решениями:

Реализация Copy/Paste
Добрый день!!!!! уважаемые форумчане подскажите кто как реализует copy/paste?????? Есть грид, в нем можно выделять несколько...

Copy >> Paste
Тянет ли копи паст под низкочастотники? Не в ту категорию пост запихал ( Как исправить?

Copy/Paste
доброго! вот у меня тут возник такой вопрос: 1.Сopy 2.Paste итак вот вопросы 1.Как сделать так что бы в виндовс приложении из...

42
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
14.03.2016, 23:37  [ТС]
Студворк — интернет-сервис помощи студентам
Огромное спасибо. Все получилось! GridData у меня уже был оказываетя, только в другой переменной) Оставалось заносить в него изменения(заполнять новые данныев соотв. члены массива) и перерисовывать. Спасибо!

Добавлено через 12 минут
Одна только осталась проблема - у меня изначально свойство goRangeSelect стоит false и все это не работало.
Поставив его в true все заработало, но перестало выделять по коду некоторые вещи(желтым по периметру например выделенные ячейки)
Как то можно побороть?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 00:32
Для того, чтобы сделать тот функционал, который у тебя был - нужно как минимум видеть, что именно было. В частности, никто не мешает по OnMouseUp грида (после того, как выбор ячеек закончен) отрисовать это самое выделение выбранных ячеек по периметру:
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::DrawGrid1MouseUp(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y)
{
    TDrawGrid *dg = static_cast<TDrawGrid*>(Sender);
    TGridRect sel = DrawGrid1->Selection;
 
    dg->Canvas->Pen->Color = clRed;
    dg->Canvas->Brush->Style = bsClear;
    dg->Canvas->Rectangle(Rect(dg->CellRect(sel.Left, sel.Top).TopLeft(),
                               dg->CellRect(sel.Right, sel.Bottom).BottomRight()));
}
, и получить:
Миниатюры
Реализация через PopupMenu функций copy and paste в DrawGrid  
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 10:06  [ТС]
Там проблема есть в том, что DrawGrid1->Selection , я так понял, позволяет выделить прямоугольную область и с ней работать.
У меня выделение работает таким образом, что можно выделить например всю нулевую строку и например 5 ячеек первой строки.Есть переменная int Grid1SelectCell[20][10]; (DrawGrid1 20 на 10)
В DrawGrid1SelectCell
C++
1
Grid1SelectCell[ACol][ARow]=1;
В DrawGrid1DrawCell
C++
1
2
if(Grid1SelectCell[ACol][ARow] != 0)
       {//желтым красим периметр ячейки
Я упростил, но примерно таким образом выделение происходит.

Добавлено через 7 минут
Пробую в циклах проходить copy paste меняя DrawGrid1->Selection на пложение ячейки, если Grid1SelectCell[i][j] != 0 , но пока как то не то.

Добавлено через 7 часов 12 минут
вот так написал - вроде работает.
в DrawGrid1DrawCell
C++
1
2
if(State.Contains(gdSelected))
{//....красим
Добавлено через 1 час 34 минуты
но мне это не совсем подходит(
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 10:17
Каким образом у тебя происходило выделение ячеек, расскажи? То есть, дословно: вот нужно тебе выбрать ячейки от предпоследней в нулевой строке до третьей в первой строке, что ты делал для этого? Просто поодиночке щелкал по ячейкам с каким-нибудь Ctrl-ом зажатым?

Сам понимаешь, чтобы копировать ячейки, они должны быть выбраны либо подряд (построчно, дошел до конца строки - начинаешь следующую с начала), либо прямоугольником. Все остальные варианты (выбрать несколько ячеек в первом ряду, потом еще несколько в третьем, и еще в седьмом ряду парочку) довольно сложны для реализации, да и не представляю, зачем это может понадобиться. Поэтому могу предложить вариант: при клике и протягивании мыши с зажатым Shift-ом выбирать последовательно клетки от той, на которой был изначальный клик до той, над которой мышь отпустили, при клике и протягивании с зажатым Ctrl-ом выбирать ячейки так же, как они выбираются при goRangeSelect = true, то есть, в виде прямоугольника. А потом, когда выбран пункт меню Paste, вставлять так, как я показал выше, начиная от выбранной ячейки и сколько было запомнено. Если тебя такой вариант устроит - чуть позже набросаю проект, как это реализовать (не очень хочется делать, если оно тебе изначально не подходит)
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 10:48  [ТС]
Цитата Сообщение от volvo Посмотреть сообщение
Все остальные варианты (выбрать несколько ячеек в первом ряду, потом еще несколько в третьем
Это не нужно.Устраивают как раз прямоугольные области.
Единственный вопрос - возможно ли сделать copy paste не через DrawGrid1->Selection
У меня при нажатой левой кнопки мыши и елозанью мышью по гриду в DrawGrid1SelectCell заполняется массив интовый 20 на 10
Grid1SelectCell[ACol][ARow]=1 при выборе ячеек. Далее он используется много где, в том числе и для подсветки выделенных ячеек.
Теперь задача определить(задать) TGridRect sel
Я пробую делать для copy вместо TGridRect sel = DrawGrid1->Selection; что то типа
C++
1
2
3
4
5
6
7
8
9
10
for(int i=0;i<20;i++)
          {
             for(int j=0;j<10;j++)
              {
                  if (Grid1SelectCell[i][j] != 0 )
                    {
                      /*TRect sel= что то, что его определяет*/
                    }
              }
          }
для paste не придумать, пока copy не понятно..
смысл всего этого - оставить goRangeSelect = 0
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 11:04
Сделал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    TPoint topleft, bottomright;
    bool stop = false;
    for (int i = 0; i < 20 && !stop; i++)
        for (int j = 0; j < 10 && !stop; j++)
        {
            if (Grid1SelectCell[i][j] != 0)
            {
                topleft = Classes::Point(i, j);
                stop = true;
            }
        }
 
    if (stop) // верхний угол был найден
    {
        stop = false;
        for (int i = 19; i > -1 && !stop; i--)
            for (int j = 9; j > -1 && !stop; j--)
            {
                if (Grid1SelectCell[i][j] != 0)
                {
                    bottomright = Classes::Point(i, j);
                    stop = true;
                }
            }
    }
. для тестового массива оно мне прекрасно нашло координаты ненулевого прямоугольника:



Потом из этих двух TPoint-ов запросто собирается TRect, если нужно.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 11:21  [ТС]
Цитата Сообщение от volvo Посмотреть сообщение
Потом из этих двух TPoint-ов запросто собирается TRect
Спасибо, все подходит. Только как это наложить в copy и paste..
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 11:24
А чего там кидать-то? Все уже сделано, осталось только подставить нужную TRect вместо Selection
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void __fastcall TForm1::Copy1Click(TObject *Sender)
{
    // тут находишь эти самые topleft и bottomright, создаешь из них TRect:
    TRect sel = Classes::Rect(topleft, bottomright);
    // дальше все без изменений
    CopySize = Point(sel.Right - sel.Left + 1, sel.Bottom - sel.Top + 1);
 
    CopyData->Clear();
    for (int i = sel.Left; i <= sel.Right; i++)
        for (int j = sel.Top; j <= sel.Bottom; j++)
        {
            CopyData->Add(GridData[i][j]);
        }
}
 
void __fastcall TForm1::Paste1Click(TObject *Sender)
{
    // достаточно найти только topleft и работать с ним
    // (я правильно понимаю, что ты выбираешь ячейку, начиная с которой будет вставка,
    // или делается как-то по другому, и при правом клике на ячейку перед выбором Paste
    // нужно запомнить, куда именно кликнули?)
    int k = 0;
    for (int i = 0; i < CopySize.x; i++)
        for (int j = 0; j < CopySize.y; j++)
            GridData[(topleft.Left + i) % 12]
                    [(topleft.Left + i) / 12 + topleft.Top + j] = CopyData->Strings[k++];
    DrawGrid1->Invalidate();
}
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 11:41  [ТС]
да, все пашет.поставил уже
C++
1
TRect sel(topleft, bottomright);
спасибо!
а чем отличается
C++
1
TRect sel = Classes::Rect(topleft, bottomright);
от
C++
1
TRect sel(topleft, bottomright);
или можно и так и эдак?

Добавлено через 11 минут
Цитата Сообщение от volvo Посмотреть сообщение
я правильно понимаю, что ты выбираешь ячейку, начиная с которой будет вставка
да, именно так, но если реализация запоминания может быть - было бы не плохо - может пригодится.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 11:48
Цитата Сообщение от Sergey_03 Посмотреть сообщение
а чем отличается
В этом случае одно и то же, иногда предпочтительней делать вторым способом, если может случиться так, что Top > Bottom или Right < Left, потому что вызов конструктора с двумя параметрами типа TPoint кроме всего прочего еще и нормализует запись (приводит к виду, когда Top < Bottom и Left < Right), функция Classes::Rect этого не делает.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 11:52  [ТС]
чегото не понятно..не узнает в paste переменной
C++
1
[BCC32 Error] Unit1.cpp(11962): E2451 Undefined symbol 'topleft'
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 12:03
Цитата Сообщение от Sergey_03 Посмотреть сообщение
если реализация запоминания может быть
Еще раз: нет ничего невозможного. Например, обрабатывать OnContextPopup:
C++
1
2
3
4
5
6
void __fastcall TForm1::DrawGrid1ContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled)
{
    // int APopupCol, APopupRow; // где-то снаружи, чтобы можно было потом использовать
    DrawGrid1->MouseToCell(MousePos.x, MousePos.y, APopupCol, APopupRow);
    Handled = false; // Показывать-таки меню, если будет true - то popup-меню не покажется
}
, и заменить в обработчике Paint-а строку заполнения грида на вот эту:
C++
1
2
            GridData[(APopupCol + i) % 12]
                    [(APopupCol + i) / 12 + APopupRow + j] = CopyData->Strings[k++];
не узнает в paste переменной
Так она должна быть либо описана локально, и первый цикл поиска - тоже, либо должна быть описана где-то в классе формы или глобально, где есть доступ и в тот момент, когда ты ищешь в матрице выбранный прямоугольник, и когда делаешь paste. Я ж тебе 1000 раз говорил: приводи тестовые проекты, у тебя там не пойми что накручено, будут ошибка за ошибкой сыпаться.
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 12:10  [ТС]
Цитата Сообщение от volvo Посмотреть сообщение
Например, обрабатывать OnContextPopup:
отлично. работает!
Цитата Сообщение от volvo Посмотреть сообщение
Так она должна быть либо описана локально
это я понимаю-
код на paste
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
TPoint topleft;
    bool stop = false;
    for (int i = 0; i < 20 && !stop; i++)
        for (int j = 0; j < 10 && !stop; j++)
        {
            if (Grid1SelectCell[i][j] != 0)
            {
                topleft = Classes::Point(i, j);
                stop = true;
            }
        }
   int k = 0;
    for (int i = 0; i < CopySize.x; i++)
        for (int j = 0; j < CopySize.y; j++)
            CurrDevImageFllename[(topleft.Left + i) % 20]
                    [(topleft.Left + i) / 20 + topleft.Top + j] = CopyData->Strings[k++];
    DrawGrid1->Invalidate();
почемуто приводит к ошибке
[BCC32 Error] Unit1.cpp(11971): E2316 'Left' is not a member of 'TPoint'
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 12:55
Ну да. Вот что значит создавать код прямо тут, в редакторе форума. Поправь:
C++
1
2
            CurrDevImageFllename[(topleft.x + i) % 20]
                    [(topleft.x + i) / 20 + topleft.y + j] = CopyData->Strings[k++];
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
15.03.2016, 13:00  [ТС]
Цитата Сообщение от volvo Посмотреть сообщение
Ну да
я уже новый Rect определил. Теперь понятно все.Спасибо.
А можно при paste присваивать нужным Grid1SelectCell единицы, начиная с места вставки?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
15.03.2016, 13:04
Ну, так там же, где заполняешь CurrDevImageFllename, по тем же координатам выставляй единицы в Grid1SelectCell

C++
1
2
3
4
5
6
{
            CurrDevImageFllename[(topleft.x + i) % 20]
                    [(topleft.x + i) / 20 + topleft.y + j] = CopyData->Strings[k++];
            Grid1SelectCell[(topleft.x + i) % 20]
                    [(topleft.x + i) / 20 + topleft.y + j] = 1;
}
, по-моему, должно работать
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
16.03.2016, 13:33  [ТС]
Спасибо, все работает.

Добавлено через 23 часа 0 минут
Еще такой вопросик - а можно сделать, что бы если попадало на выделенную ячейку (Grid1SelectCell[A][B] == 1), снимался признак, то есть становилось Grid1SelectCell[A][B] = 0 ?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
16.03.2016, 13:38
Если что попадало?
1
21 / 9 / 4
Регистрация: 15.12.2014
Сообщений: 663
16.03.2016, 13:43  [ТС]
выделении ячеек. я веду по гриду мышью - например в нулевой строке - с 0 по 10 ячейку выделил, потом передумал и на две влево сдвинул мышь. По типу, как при Selection чтобы работало. Если это конечно реально.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33479 / 21577 / 8250
Регистрация: 22.10.2011
Сообщений: 37,040
Записей в блоге: 12
16.03.2016, 13:56
Проблема вся в том, что ты вообще не рассказал, как у тебя тот массив Grid1SelectCell заполняется 1-цами, вот когда расскажешь, где именно (в каком событии, при каких условиях) происходит его заполнение - тогда можно будет что-то советовать.

Не верю, что просто по OnMouseMove проверяется признак "кнопка мыши зажата", и если да, то для ячейки, над которой находится мышь, выставляется 1 в Grid1SelectCell.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.03.2016, 13:56

Copy-Paste VIM
Как выделить и сделать копи-пейст?

RichTextBox и Copy/Paste
В общем столкнулся с проблемой копирования и вставки данных из буфера обмена в поле RichTextBox. Во-первых, горячие клавиши (Ctrl +...

Запрет на copy/paste
как сделать так чтоб при открытии ексель запускалась прога которая блокирует копирование и вставку ?

Не работает Copy\paste
Доброго времени суток. Не ожидал что увижу такое... в базе не работает Copy\Paste Посмотрел другие базы, там все норм. Сравнил...

Copy/Paste текста в Word
Уважаемые! Не сочтите за труд, подскажите - что не так делаю? Нужно: - открыть в фоновом режиме источник (путь - FileSource); -...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru